/* coroutine-specific state, expansions and tests.

   Copyright (C) 2018-2022 Free Software Foundation, Inc.

 Contributed by Iain Sandoe <iain@sandoe.co.uk> under contract to Facebook.

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 "target.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "stmt.h"
#include "stor-layout.h"
#include "tree-iterator.h"
#include "tree.h"
#include "gcc-rich-location.h"
#include "hash-map.h"

static bool coro_promise_type_found_p (tree, location_t);

/* GCC C++ coroutines implementation.

  The user authors a function that becomes a coroutine (lazily) by
  making use of any of the co_await, co_yield or co_return keywords.

  Unlike a regular function, where the activation record is placed on the
  stack, and is destroyed on function exit, a coroutine has some state that
  persists between calls - the coroutine frame (analogous to a stack frame).

  We transform the user's function into three pieces:
  1. A so-called ramp function, that establishes the coroutine frame and
     begins execution of the coroutine.
  2. An actor function that contains the state machine corresponding to the
     user's suspend/resume structure.
  3. A stub function that calls the actor function in 'destroy' mode.

  The actor function is executed:
   * from "resume point 0" by the ramp.
   * from resume point N ( > 0 ) for handle.resume() calls.
   * from the destroy stub for destroy point N for handle.destroy() calls.

  The functions in this file carry out the necessary analysis of, and
  transforms to, the AST to perform this.

  The C++ coroutine design makes use of some helper functions that are
  authored in a so-called "promise" class provided by the user.

  At parse time (or post substitution) the type of the coroutine promise
  will be determined.  At that point, we can look up the required promise
  class methods and issue diagnostics if they are missing or incorrect.  To
  avoid repeating these actions at code-gen time, we make use of temporary
  'proxy' variables for the coroutine handle and the promise - which will
  eventually be instantiated in the coroutine frame.

  Each of the keywords will expand to a code sequence (although co_yield is
  just syntactic sugar for a co_await).

  We defer the analysis and transformation until template expansion is
  complete so that we have complete types at that time.  */


/* The state that we collect during parsing (and template expansion) for
   a coroutine.  */

struct GTY((for_user)) coroutine_info
{
  tree function_decl; /* The original function decl.  */
  tree actor_decl;    /* The synthesized actor function.  */
  tree destroy_decl;  /* The synthesized destroy function.  */
  tree promise_type;  /* The cached promise type for this function.  */
  tree handle_type;   /* The cached coroutine handle for this function.  */
  tree self_h_proxy;  /* A handle instance that is used as the proxy for the
			 one that will eventually be allocated in the coroutine
			 frame.  */
  tree promise_proxy; /* Likewise, a proxy promise instance.  */
  tree return_void;   /* The expression for p.return_void() if it exists.  */
  location_t first_coro_keyword; /* The location of the keyword that made this
				    function into a coroutine.  */
  /* Flags to avoid repeated errors for per-function issues.  */
  bool coro_ret_type_error_emitted;
  bool coro_promise_error_emitted;
  bool coro_co_return_error_emitted;
};

struct coroutine_info_hasher : ggc_ptr_hash<coroutine_info>
{
  typedef tree compare_type; /* We only compare the function decl.  */
  static inline hashval_t hash (coroutine_info *);
  static inline hashval_t hash (const compare_type &);
  static inline bool equal (coroutine_info *, coroutine_info *);
  static inline bool equal (coroutine_info *, const compare_type &);
};

/* This table holds all the collected coroutine state for coroutines in
   the current translation unit.  */

static GTY (()) hash_table<coroutine_info_hasher> *coroutine_info_table;

/* We will initialize state lazily.  */
static bool coro_initialized = false;

/* Return a hash value for the entry pointed to by INFO.
   The compare type is a tree, but the only trees we are going use are
   function decls.  We use the DECL_UID as the hash value since that is
   stable across PCH.  */

hashval_t
coroutine_info_hasher::hash (coroutine_info *info)
{
  return DECL_UID (info->function_decl);
}

/* Return a hash value for the compare value COMP.  */

hashval_t
coroutine_info_hasher::hash (const compare_type& comp)
{
  return DECL_UID (comp);
}

/* Return true if the entries pointed to by LHS and RHS are for the
   same coroutine.  */

bool
coroutine_info_hasher::equal (coroutine_info *lhs, coroutine_info *rhs)
{
  return lhs->function_decl == rhs->function_decl;
}

bool
coroutine_info_hasher::equal (coroutine_info *lhs, const compare_type& rhs)
{
  return lhs->function_decl == rhs;
}

/* Get the existing coroutine_info for FN_DECL, or insert a new one if the
   entry does not yet exist.  */

coroutine_info *
get_or_insert_coroutine_info (tree fn_decl)
{
  gcc_checking_assert (coroutine_info_table != NULL);

  coroutine_info **slot = coroutine_info_table->find_slot_with_hash
    (fn_decl, coroutine_info_hasher::hash (fn_decl), INSERT);

  if (*slot == NULL)
    {
      *slot = new (ggc_cleared_alloc<coroutine_info> ()) coroutine_info ();
      (*slot)->function_decl = fn_decl;
    }

  return *slot;
}

/* Get the existing coroutine_info for FN_DECL, fail if it doesn't exist.  */

coroutine_info *
get_coroutine_info (tree fn_decl)
{
  if (coroutine_info_table == NULL)
    return NULL;

  coroutine_info **slot = coroutine_info_table->find_slot_with_hash
    (fn_decl, coroutine_info_hasher::hash (fn_decl), NO_INSERT);
  if (slot)
    return *slot;
  return NULL;
}

/* We will lazily create all the identifiers that are used by coroutines
   on the first attempt to lookup the traits.  */

/* Identifiers that are used by all coroutines.  */

static GTY(()) tree coro_traits_identifier;
static GTY(()) tree coro_handle_identifier;
static GTY(()) tree coro_promise_type_identifier;

/* Required promise method name identifiers.  */

static GTY(()) tree coro_await_transform_identifier;
static GTY(()) tree coro_initial_suspend_identifier;
static GTY(()) tree coro_final_suspend_identifier;
static GTY(()) tree coro_return_void_identifier;
static GTY(()) tree coro_return_value_identifier;
static GTY(()) tree coro_yield_value_identifier;
static GTY(()) tree coro_resume_identifier;
static GTY(()) tree coro_address_identifier;
static GTY(()) tree coro_from_address_identifier;
static GTY(()) tree coro_get_return_object_identifier;
static GTY(()) tree coro_gro_on_allocation_fail_identifier;
static GTY(()) tree coro_unhandled_exception_identifier;

/* Awaitable methods.  */

static GTY(()) tree coro_await_ready_identifier;
static GTY(()) tree coro_await_suspend_identifier;
static GTY(()) tree coro_await_resume_identifier;

/* Accessors for the coroutine frame state used by the implementation.  */

static GTY(()) tree coro_resume_fn_id;
static GTY(()) tree coro_destroy_fn_id;
static GTY(()) tree coro_promise_id;
static GTY(()) tree coro_frame_needs_free_id;
static GTY(()) tree coro_resume_index_id;
static GTY(()) tree coro_self_handle_id;
static GTY(()) tree coro_actor_continue_id;
static GTY(()) tree coro_frame_i_a_r_c_id;

/* Create the identifiers used by the coroutines library interfaces and
   the implementation frame state.  */

static void
coro_init_identifiers ()
{
  coro_traits_identifier = get_identifier ("coroutine_traits");
  coro_handle_identifier = get_identifier ("coroutine_handle");
  coro_promise_type_identifier = get_identifier ("promise_type");

  coro_await_transform_identifier = get_identifier ("await_transform");
  coro_initial_suspend_identifier = get_identifier ("initial_suspend");
  coro_final_suspend_identifier = get_identifier ("final_suspend");
  coro_return_void_identifier = get_identifier ("return_void");
  coro_return_value_identifier = get_identifier ("return_value");
  coro_yield_value_identifier = get_identifier ("yield_value");
  coro_resume_identifier = get_identifier ("resume");
  coro_address_identifier = get_identifier ("address");
  coro_from_address_identifier = get_identifier ("from_address");
  coro_get_return_object_identifier = get_identifier ("get_return_object");
  coro_gro_on_allocation_fail_identifier =
    get_identifier ("get_return_object_on_allocation_failure");
  coro_unhandled_exception_identifier = get_identifier ("unhandled_exception");

  coro_await_ready_identifier = get_identifier ("await_ready");
  coro_await_suspend_identifier = get_identifier ("await_suspend");
  coro_await_resume_identifier = get_identifier ("await_resume");

  /* Coroutine state frame field accessors.  */
  coro_resume_fn_id = get_identifier ("_Coro_resume_fn");
  coro_destroy_fn_id = get_identifier ("_Coro_destroy_fn");
  coro_promise_id = get_identifier ("_Coro_promise");
  coro_frame_needs_free_id = get_identifier ("_Coro_frame_needs_free");
  coro_frame_i_a_r_c_id = get_identifier ("_Coro_initial_await_resume_called");
  coro_resume_index_id = get_identifier ("_Coro_resume_index");
  coro_self_handle_id = get_identifier ("_Coro_self_handle");
  coro_actor_continue_id = get_identifier ("_Coro_actor_continue");
}

/* Trees we only need to set up once.  */

static GTY(()) tree coro_traits_templ;
static GTY(()) tree coro_handle_templ;
static GTY(()) tree void_coro_handle_type;

/* ================= Parse, Semantics and Type checking ================= */

/* This initial set of routines are helper for the parsing and template
   expansion phases.

   At the completion of this, we will have completed trees for each of the
   keywords, but making use of proxy variables for the self-handle and the
   promise class instance.  */

/* [coroutine.traits]
   Lookup the coroutine_traits template decl.  */

static tree
find_coro_traits_template_decl (location_t kw)
{
  /* If we are missing fundamental information, such as the traits, (or the
     declaration found is not a type template), then don't emit an error for
     every keyword in a TU, just do it once.  */
  static bool traits_error_emitted = false;

  tree traits_decl = lookup_qualified_name (std_node, coro_traits_identifier,
					    LOOK_want::NORMAL,
					    /*complain=*/!traits_error_emitted);
  if (traits_decl == error_mark_node
      || !DECL_TYPE_TEMPLATE_P (traits_decl))
    {
      if (!traits_error_emitted)
	{
	  gcc_rich_location richloc (kw);
	  error_at (&richloc, "coroutines require a traits template; cannot"
		    " find %<%E::%E%>", std_node, coro_traits_identifier);
	  inform (&richloc, "perhaps %<#include <coroutine>%> is missing");
	  traits_error_emitted = true;
	}
      return NULL_TREE;
    }
  else
    return traits_decl;
}

/*  Instantiate Coroutine traits for the function signature.  */

static tree
instantiate_coro_traits (tree fndecl, location_t kw)
{
  /* [coroutine.traits.primary]
     So now build up a type list for the template <typename _R, typename...>.
     The types are the function's arg types and _R is the function return
     type.  */

  tree functyp = TREE_TYPE (fndecl);
  tree arg = DECL_ARGUMENTS (fndecl);
  tree arg_node = TYPE_ARG_TYPES (functyp);
  tree argtypes = make_tree_vec (list_length (arg_node)-1);
  unsigned p = 0;

  while (arg_node != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (arg_node)))
    {
      if (is_this_parameter (arg)
	  || DECL_NAME (arg) == closure_identifier)
	{
	  /* We pass a reference to *this to the param preview.  */
	  tree ct = TREE_TYPE (TREE_TYPE (arg));
	  TREE_VEC_ELT (argtypes, p++) = cp_build_reference_type (ct, false);
	}
      else
	TREE_VEC_ELT (argtypes, p++) = TREE_VALUE (arg_node);

      arg_node = TREE_CHAIN (arg_node);
      arg = DECL_CHAIN (arg);
    }

  tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
  SET_ARGUMENT_PACK_ARGS (argtypepack, argtypes);

  tree targ = make_tree_vec (2);
  TREE_VEC_ELT (targ, 0) = TREE_TYPE (functyp);
  TREE_VEC_ELT (targ, 1) = argtypepack;

  tree traits_class
    = lookup_template_class (coro_traits_templ, targ,
			     /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE,
			     /*entering scope=*/false, tf_warning_or_error);

  if (traits_class == error_mark_node)
    {
      error_at (kw, "cannot instantiate %<coroutine traits%>");
      return NULL_TREE;
    }

  return traits_class;
}

/* [coroutine.handle] */

static tree
find_coro_handle_template_decl (location_t kw)
{
  /* As for the coroutine traits, this error is per TU, so only emit
    it once.  */
  static bool coro_handle_error_emitted = false;
  tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier,
					    LOOK_want::NORMAL,
					    !coro_handle_error_emitted);
  if (handle_decl == error_mark_node
      || !DECL_CLASS_TEMPLATE_P (handle_decl))
    {
      if (!coro_handle_error_emitted)
	error_at (kw, "coroutines require a handle class template;"
		  " cannot find %<%E::%E%>", std_node, coro_handle_identifier);
      coro_handle_error_emitted = true;
      return NULL_TREE;
    }
  else
    return handle_decl;
}

/* Instantiate the handle template for a given promise type.  */

static tree
instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type)
{
  /* So now build up a type list for the template, one entry, the promise.  */
  tree targ = make_tree_vec (1);
  TREE_VEC_ELT (targ, 0) = promise_type;
  tree handle_type
    = lookup_template_class (coro_handle_identifier, targ,
			     /* in_decl=*/NULL_TREE,
			     /* context=*/std_node,
			     /* entering scope=*/false, tf_warning_or_error);

  if (handle_type == error_mark_node)
    {
      error_at (kw, "cannot instantiate a %<coroutine handle%> for"
		" promise type %qT", promise_type);
      return NULL_TREE;
    }

  return handle_type;
}

/* Look for the promise_type in the instantiated traits.  */

static tree
find_promise_type (tree traits_class)
{
  tree promise_type
    = lookup_member (traits_class, coro_promise_type_identifier,
		     /* protect=*/1, /*want_type=*/true, tf_warning_or_error);

  if (promise_type)
    promise_type
      = complete_type_or_else (TREE_TYPE (promise_type), promise_type);

  /* NULL_TREE on fail.  */
  return promise_type;
}

static bool
coro_promise_type_found_p (tree fndecl, location_t loc)
{
  gcc_assert (fndecl != NULL_TREE);

  if (!coro_initialized)
    {
      /* Trees we only need to create once.
	 Set up the identifiers we will use.  */
      coro_init_identifiers ();

      /* Coroutine traits template.  */
      coro_traits_templ = find_coro_traits_template_decl (loc);
      if (coro_traits_templ == NULL_TREE)
	return false;

      /*  coroutine_handle<> template.  */
      coro_handle_templ = find_coro_handle_template_decl (loc);
      if (coro_handle_templ == NULL_TREE)
	return false;

      /*  We can also instantiate the void coroutine_handle<>  */
      void_coro_handle_type =
	instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
      if (void_coro_handle_type == NULL_TREE)
	return false;

      /* A table to hold the state, per coroutine decl.  */
      gcc_checking_assert (coroutine_info_table == NULL);
      coroutine_info_table =
	hash_table<coroutine_info_hasher>::create_ggc (11);

      if (coroutine_info_table == NULL)
	return false;

      coro_initialized = true;
    }

  /* Save the coroutine data on the side to avoid the overhead on every
     function decl tree.  */

  coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
  /* Without this, we cannot really proceed.  */
  gcc_checking_assert (coro_info);

  /* If we don't already have a current promise type, try to look it up.  */
  if (coro_info->promise_type == NULL_TREE)
    {
      /* Get the coroutine traits template class instance for the function
	 signature we have - coroutine_traits <R, ...>  */

      tree templ_class = instantiate_coro_traits (fndecl, loc);

      /* Find the promise type for that.  */
      coro_info->promise_type = find_promise_type (templ_class);

      /* If we don't find it, punt on the rest.  */
      if (coro_info->promise_type == NULL_TREE)
	{
	  if (!coro_info->coro_promise_error_emitted)
	    error_at (loc, "unable to find the promise type for"
		      " this coroutine");
	  coro_info->coro_promise_error_emitted = true;
	  return false;
	}

      /* Test for errors in the promise type that can be determined now.  */
      tree has_ret_void = lookup_member (coro_info->promise_type,
					 coro_return_void_identifier,
					 /*protect=*/1, /*want_type=*/0,
					 tf_none);
      tree has_ret_val = lookup_member (coro_info->promise_type,
					coro_return_value_identifier,
					/*protect=*/1, /*want_type=*/0,
					tf_none);
      if (has_ret_void && has_ret_val)
	{
	  location_t ploc = DECL_SOURCE_LOCATION (fndecl);
	  if (!coro_info->coro_co_return_error_emitted)
	    error_at (ploc, "the coroutine promise type %qT declares both"
		      " %<return_value%> and %<return_void%>",
		      coro_info->promise_type);
	  inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_void)),
		  "%<return_void%> declared here");
	  inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_val)),
		  "%<return_value%> declared here");
	  coro_info->coro_co_return_error_emitted = true;
	  return false;
	}

      /* Try to find the handle type for the promise.  */
      tree handle_type =
	instantiate_coro_handle_for_promise_type (loc, coro_info->promise_type);
      if (handle_type == NULL_TREE)
	return false;

      /* Complete this, we're going to use it.  */
      coro_info->handle_type = complete_type_or_else (handle_type, fndecl);

      /* Diagnostic would be emitted by complete_type_or_else.  */
      if (!coro_info->handle_type)
	return false;

      /* Build a proxy for a handle to "self" as the param to
	 await_suspend() calls.  */
      coro_info->self_h_proxy
	= build_lang_decl (VAR_DECL, coro_self_handle_id,
			   coro_info->handle_type);

      /* Build a proxy for the promise so that we can perform lookups.  */
      coro_info->promise_proxy
	= build_lang_decl (VAR_DECL, coro_promise_id,
			   coro_info->promise_type);

      /* Note where we first saw a coroutine keyword.  */
      coro_info->first_coro_keyword = loc;
    }

  return true;
}

/* Map from actor or destroyer to ramp.  */
static GTY(()) hash_map<tree, tree> *to_ramp;

/* Given a tree that is an actor or destroy, find the ramp function.  */

tree
coro_get_ramp_function (tree decl)
{
  if (!to_ramp)
    return NULL_TREE;
  tree *p = to_ramp->get (decl);
  if (p)
    return *p;
  return NULL_TREE;
}

/* Given the DECL for a ramp function (the user's original declaration) return
   the actor function if it has been defined.  */

tree
coro_get_actor_function (tree decl)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    return info->actor_decl;

  return NULL_TREE;
}

/* Given the DECL for a ramp function (the user's original declaration) return
   the destroy function if it has been defined.  */

tree
coro_get_destroy_function (tree decl)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    return info->destroy_decl;

  return NULL_TREE;
}

/* These functions assumes that the caller has verified that the state for
   the decl has been initialized, we try to minimize work here.  */

static tree
get_coroutine_promise_type (tree decl)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    return info->promise_type;

  return NULL_TREE;
}

static tree
get_coroutine_handle_type (tree decl)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    return info->handle_type;

  return NULL_TREE;
}

static tree
get_coroutine_self_handle_proxy (tree decl)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    return info->self_h_proxy;

  return NULL_TREE;
}

static tree
get_coroutine_promise_proxy (tree decl)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    return info->promise_proxy;

  return NULL_TREE;
}

static tree
lookup_promise_method (tree fndecl, tree member_id, location_t loc,
		       bool musthave)
{
  tree promise = get_coroutine_promise_type (fndecl);
  tree pm_memb
    = lookup_member (promise, member_id,
		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
  if (musthave && pm_memb == NULL_TREE)
    {
      error_at (loc, "no member named %qE in %qT", member_id, promise);
      return error_mark_node;
    }
  return pm_memb;
}

/* Build an expression of the form p.method (args) where the p is a promise
   object for the current coroutine.
   OBJECT is the promise object instance to use, it may be NULL, in which case
   we will use the promise_proxy instance for this coroutine.
   ARGS may be NULL, for empty parm lists.  */

static tree
coro_build_promise_expression (tree fn, tree promise_obj, tree member_id,
			       location_t loc, vec<tree, va_gc> **args,
			       bool musthave)
{
  tree meth = lookup_promise_method (fn, member_id, loc, musthave);
  if (meth == error_mark_node)
    return error_mark_node;

  /* If we don't find it, and it isn't needed, an empty return is OK.  */
  if (!meth)
    return NULL_TREE;

  tree promise
    = promise_obj ? promise_obj
		  : get_coroutine_promise_proxy (current_function_decl);
  tree expr;
  if (BASELINK_P (meth))
    expr = build_new_method_call (promise, meth, args, NULL_TREE,
				  LOOKUP_NORMAL, NULL, tf_warning_or_error);
  else
    {
      expr = build_class_member_access_expr (promise, meth, NULL_TREE,
					     true, tf_warning_or_error);
      vec<tree, va_gc> *real_args;
      if (!args)
	real_args = make_tree_vector ();
      else
	real_args = *args;
      expr = build_op_call (expr, &real_args, tf_warning_or_error);
    }
  return expr;
}

/* Caching get for the expression p.return_void ().  */

static tree
get_coroutine_return_void_expr (tree decl, location_t loc, bool musthave)
{
  if (coroutine_info *info = get_coroutine_info (decl))
    {
      /* If we don't have it try to build it.  */
      if (!info->return_void)
	info->return_void
	  = coro_build_promise_expression (current_function_decl, NULL,
					   coro_return_void_identifier,
					   loc, NULL, musthave);
      /* Don't return an error if it's an optional call.  */
      if (!musthave && info->return_void == error_mark_node)
	return NULL_TREE;
      return info->return_void;
    }
  return musthave ? error_mark_node : NULL_TREE;
}

/* Lookup an Awaitable member, which should be await_ready, await_suspend
   or await_resume.  */

static tree
lookup_awaitable_member (tree await_type, tree member_id, location_t loc)
{
  tree aw_memb
    = lookup_member (await_type, member_id,
		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
  if (aw_memb == NULL_TREE)
    {
      error_at (loc, "no member named %qE in %qT", member_id, await_type);
      return error_mark_node;
    }
  return aw_memb;
}

/* Here we check the constraints that are common to all keywords (since the
   presence of a coroutine keyword makes the function into a coroutine).  */

static bool
coro_common_keyword_context_valid_p (tree fndecl, location_t kw_loc,
				     const char *kw_name)
{
  if (fndecl == NULL_TREE)
    {
      error_at (kw_loc, "%qs cannot be used outside a function", kw_name);
      return false;
    }

  /* This is arranged in order of prohibitions in the std.  */
  if (DECL_MAIN_P (fndecl))
    {
      /* [basic.start.main] 3. The function main shall not be a coroutine.  */
      error_at (kw_loc, "%qs cannot be used in the %<main%> function",
		kw_name);
      return false;
    }

  if (DECL_DECLARED_CONSTEXPR_P (fndecl))
    {
      cp_function_chain->invalid_constexpr = true;
      if (!is_instantiation_of_constexpr (fndecl))
	{
	  /* [dcl.constexpr] 3.3 it shall not be a coroutine.  */
	  error_at (kw_loc, "%qs cannot be used in a %<constexpr%> function",
		    kw_name);
	  return false;
	}
    }

  if (FNDECL_USED_AUTO (fndecl))
    {
      /* [dcl.spec.auto] 15. A function declared with a return type that uses
	 a placeholder type shall not be a coroutine.  */
      error_at (kw_loc,
		"%qs cannot be used in a function with a deduced return type",
		kw_name);
      return false;
    }

  if (varargs_function_p (fndecl))
    {
      /* [dcl.fct.def.coroutine] The parameter-declaration-clause of the
	 coroutine shall not terminate with an ellipsis that is not part
	 of a parameter-declaration.  */
      error_at (kw_loc,
		"%qs cannot be used in a varargs function", kw_name);
      return false;
    }

  if (DECL_CONSTRUCTOR_P (fndecl))
    {
      /* [class.ctor] 7. a constructor shall not be a coroutine.  */
      error_at (kw_loc, "%qs cannot be used in a constructor", kw_name);
      return false;
    }

  if (DECL_DESTRUCTOR_P (fndecl))
    {
      /* [class.dtor] 21. a destructor shall not be a coroutine.  */
      error_at (kw_loc, "%qs cannot be used in a destructor", kw_name);
      return false;
    }

  return true;
}

/* Here we check the constraints that are not per keyword.  */

static bool
coro_function_valid_p (tree fndecl)
{
  location_t f_loc = DECL_SOURCE_LOCATION (fndecl);

  /* For cases where fundamental information cannot be found, e.g. the
     coroutine traits are missing, we need to punt early.  */
  if (!coro_promise_type_found_p (fndecl, f_loc))
    return false;

  /* Since we think the function is a coroutine, that implies we parsed
     a keyword that triggered this.  Keywords check promise validity for
     their context and thus the promise type should be known at this point.  */
  if (get_coroutine_handle_type (fndecl) == NULL_TREE
      || get_coroutine_promise_type (fndecl) == NULL_TREE)
    return false;

  if (current_function_returns_value || current_function_returns_null)
    {
       /* TODO: record or extract positions of returns (and the first coro
	  keyword) so that we can add notes to the diagnostic about where
	  the bad keyword is and what made the function into a coro.  */
      error_at (f_loc, "a %<return%> statement is not allowed in coroutine;"
			" did you mean %<co_return%>?");
      return false;
    }

  return true;
}

enum suspend_point_kind {
  CO_AWAIT_SUSPEND_POINT = 0,
  CO_YIELD_SUSPEND_POINT,
  INITIAL_SUSPEND_POINT,
  FINAL_SUSPEND_POINT
};

/* Helper function to build a named variable for the temps we use for each
   await point.  The root of the name is determined by SUSPEND_KIND, and
   the variable is of type V_TYPE.  The awaitable number is reset each time
   we encounter a final suspend.  */

static tree
get_awaitable_var (suspend_point_kind suspend_kind, tree v_type)
{
  static int awn = 0;
  char *buf;
  switch (suspend_kind)
    {
      default: buf = xasprintf ("Aw%d", awn++); break;
      case CO_YIELD_SUSPEND_POINT: buf =  xasprintf ("Yd%d", awn++); break;
      case INITIAL_SUSPEND_POINT: buf =  xasprintf ("Is"); break;
      case FINAL_SUSPEND_POINT: buf =  xasprintf ("Fs"); awn = 0; break;
  }
  tree ret = get_identifier (buf);
  free (buf);
  ret = build_lang_decl (VAR_DECL, ret, v_type);
  DECL_ARTIFICIAL (ret) = true;
  return ret;
}

/* Helpers to diagnose missing noexcept on final await expressions.  */

static bool
coro_diagnose_throwing_fn (tree fndecl)
{
  if (!TYPE_NOTHROW_P (TREE_TYPE (fndecl)))
    {
      location_t f_loc = cp_expr_loc_or_loc (fndecl,
					     DECL_SOURCE_LOCATION (fndecl));
      error_at (f_loc, "the expression %qE is required to be non-throwing",
		fndecl);
      inform (f_loc, "must be declared with %<noexcept(true)%>");
      return true;
    }
  return false;
}

static bool
coro_diagnose_throwing_final_aw_expr (tree expr)
{
  tree t = TARGET_EXPR_INITIAL (expr);
  tree fn = NULL_TREE;
  if (TREE_CODE (t) == CALL_EXPR)
    fn = CALL_EXPR_FN(t);
  else if (TREE_CODE (t) == AGGR_INIT_EXPR)
    fn = AGGR_INIT_EXPR_FN (t);
  else if (TREE_CODE (t) == CONSTRUCTOR)
    return false;
  else
    {
      gcc_checking_assert (0 && "unhandled expression type");
      return false;
    }
  fn = TREE_OPERAND (fn, 0);
  return coro_diagnose_throwing_fn (fn);
}

/*  This performs [expr.await] bullet 3.3 and validates the interface obtained.
    It is also used to build the initial and final suspend points.

    'a', 'o' and 'e' are used as per the description in the section noted.

    A, the original yield/await expr, is found at source location LOC.

    We will be constructing a CO_AWAIT_EXPR for a suspend point of one of
    the four suspend_point_kind kinds.  This is indicated by SUSPEND_KIND.  */

static tree
build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind)
{
  /* Try and overload of operator co_await, .... */
  tree o;
  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (a)))
    {
      o = build_new_op (loc, CO_AWAIT_EXPR, LOOKUP_NORMAL, a, NULL_TREE,
			NULL_TREE, NULL_TREE, NULL, tf_warning_or_error);
      /* If no viable functions are found, o is a.  */
      if (!o || o == error_mark_node)
	o = a;
      else if (flag_exceptions && suspend_kind == FINAL_SUSPEND_POINT)
	{
	  /* We found an overload for co_await(), diagnose throwing cases.  */
	  if (TREE_CODE (o) == TARGET_EXPR
	      && coro_diagnose_throwing_final_aw_expr (o))
	    return error_mark_node;

	  /* We now know that the final suspend object is distinct from the
	     final awaiter, so check for a non-throwing DTOR where needed.  */
	  tree a_type = TREE_TYPE (a);
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (a_type))
	    if (tree dummy
		= build_special_member_call (a, complete_dtor_identifier,
					     NULL, a_type, LOOKUP_NORMAL,
					     tf_none))
	      {
		if (CONVERT_EXPR_P (dummy))
		  dummy = TREE_OPERAND (dummy, 0);
		dummy = TREE_OPERAND (CALL_EXPR_FN (dummy), 0);
		if (coro_diagnose_throwing_fn (dummy))
		  return error_mark_node;
	      }
	}
    }
  else
    o = a; /* This is most likely about to fail anyway.  */

  tree o_type = TREE_TYPE (o);
  if (o_type && !VOID_TYPE_P (o_type))
    o_type = complete_type_or_else (o_type, o);

  if (!o_type)
    return error_mark_node;

  if (TREE_CODE (o_type) != RECORD_TYPE)
    {
      error_at (loc, "awaitable type %qT is not a structure",
		o_type);
      return error_mark_node;
    }

  /* Check for required awaitable members and their types.  */
  tree awrd_meth
    = lookup_awaitable_member (o_type, coro_await_ready_identifier, loc);
  if (!awrd_meth || awrd_meth == error_mark_node)
    return error_mark_node;
  tree awsp_meth
    = lookup_awaitable_member (o_type, coro_await_suspend_identifier, loc);
  if (!awsp_meth || awsp_meth == error_mark_node)
    return error_mark_node;

  /* The type of the co_await is the return type of the awaitable's
     await_resume, so we need to look that up.  */
  tree awrs_meth
    = lookup_awaitable_member (o_type, coro_await_resume_identifier, loc);
  if (!awrs_meth || awrs_meth == error_mark_node)
    return error_mark_node;

  /* To complete the lookups, we need an instance of 'e' which is built from
     'o' according to [expr.await] 3.4.

     If we need to materialize this as a temporary, then that will have to be
     'promoted' to a coroutine frame var.  However, if the awaitable is a
     user variable, parameter or comes from a scope outside this function,
     then we must use it directly - or we will see unnecessary copies.

     If o is a variable, find the underlying var.  */
  tree e_proxy = STRIP_NOPS (o);
  if (INDIRECT_REF_P (e_proxy))
    e_proxy = TREE_OPERAND (e_proxy, 0);
  while (TREE_CODE (e_proxy) == COMPONENT_REF)
    {
      e_proxy = TREE_OPERAND (e_proxy, 0);
      if (INDIRECT_REF_P (e_proxy))
	e_proxy = TREE_OPERAND (e_proxy, 0);
      if (TREE_CODE (e_proxy) == CALL_EXPR)
	{
	  /* We could have operator-> here too.  */
	  tree op = TREE_OPERAND (CALL_EXPR_FN (e_proxy), 0);
	  if (DECL_OVERLOADED_OPERATOR_P (op)
	      && DECL_OVERLOADED_OPERATOR_IS (op, COMPONENT_REF))
	    {
	      e_proxy = CALL_EXPR_ARG (e_proxy, 0);
	      STRIP_NOPS (e_proxy);
	      gcc_checking_assert (TREE_CODE (e_proxy) == ADDR_EXPR);
	      e_proxy = TREE_OPERAND (e_proxy, 0);
	    }
	}
      STRIP_NOPS (e_proxy);
    }

  /* Only build a temporary if we need it.  */
  STRIP_NOPS (e_proxy);
  if (TREE_CODE (e_proxy) == PARM_DECL
      || (VAR_P (e_proxy) && !is_local_temp (e_proxy)))
    {
      e_proxy = o;
      o = NULL_TREE; /* The var is already present.  */
    }
  else
    {
      e_proxy = get_awaitable_var (suspend_kind, o_type);
      o = cp_build_modify_expr (loc, e_proxy, INIT_EXPR, o,
				tf_warning_or_error);
    }

  /* I suppose we could check that this is contextually convertible to bool.  */
  tree awrd_func = NULL_TREE;
  tree awrd_call
    = build_new_method_call (e_proxy, awrd_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
			     &awrd_func, tf_warning_or_error);

  if (!awrd_func || !awrd_call || awrd_call == error_mark_node)
    return error_mark_node;

  /* The suspend method may return one of three types:
      1. void (no special action needed).
      2. bool (if true, we don't need to suspend).
      3. a coroutine handle, we execute the handle.resume() call.  */
  tree awsp_func = NULL_TREE;
  tree h_proxy = get_coroutine_self_handle_proxy (current_function_decl);
  vec<tree, va_gc> *args = make_tree_vector_single (h_proxy);
  tree awsp_call
    = build_new_method_call (e_proxy, awsp_meth, &args, NULL_TREE,
			     LOOKUP_NORMAL, &awsp_func, tf_warning_or_error);

  release_tree_vector (args);
  if (!awsp_func || !awsp_call || awsp_call == error_mark_node)
    return error_mark_node;

  bool ok = false;
  tree susp_return_type = TREE_TYPE (TREE_TYPE (awsp_func));
  if (same_type_p (susp_return_type, void_type_node))
    ok = true;
  else if (same_type_p (susp_return_type, boolean_type_node))
    ok = true;
  else if (TREE_CODE (susp_return_type) == RECORD_TYPE
	   && CLASS_TYPE_P (susp_return_type)
	   && CLASSTYPE_TEMPLATE_INFO (susp_return_type))
    {
      tree tt = CLASSTYPE_TI_TEMPLATE (susp_return_type);
      if (tt == coro_handle_templ)
	ok = true;
    }

  if (!ok)
    {
      error_at (loc, "%<await_suspend%> must return %<void%>, %<bool%> or"
		     " a coroutine handle");
      return error_mark_node;
    }

  /* Finally, the type of e.await_resume() is the co_await's type.  */
  tree awrs_func = NULL_TREE;
  tree awrs_call
    = build_new_method_call (e_proxy, awrs_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
			     &awrs_func, tf_warning_or_error);

  if (!awrs_func || !awrs_call || awrs_call == error_mark_node)
    return error_mark_node;

  if (flag_exceptions && suspend_kind == FINAL_SUSPEND_POINT)
    {
      if (coro_diagnose_throwing_fn (awrd_func))
	return error_mark_node;
      if (coro_diagnose_throwing_fn (awsp_func))
	return error_mark_node;
      if (coro_diagnose_throwing_fn (awrs_func))
	return error_mark_node;
      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (o_type))
	if (tree dummy
	    = build_special_member_call (e_proxy, complete_dtor_identifier,
					 NULL, o_type, LOOKUP_NORMAL,
					 tf_none))
	  {
	    if (CONVERT_EXPR_P (dummy))
	      dummy = TREE_OPERAND (dummy, 0);
	    dummy = TREE_OPERAND (CALL_EXPR_FN (dummy), 0);
	    if (coro_diagnose_throwing_fn (dummy))
	      return error_mark_node;
	  }
    }

  /* We now have three call expressions, in terms of the promise, handle and
     'e' proxies.  Save them in the await expression for later expansion.  */

  tree awaiter_calls = make_tree_vec (3);
  TREE_VEC_ELT (awaiter_calls, 0) = awrd_call; /* await_ready().  */
  TREE_VEC_ELT (awaiter_calls, 1) = awsp_call; /* await_suspend().  */
  tree te = NULL_TREE;
  if (TREE_CODE (awrs_call) == TARGET_EXPR)
    {
      te = awrs_call;
      awrs_call = TREE_OPERAND (awrs_call, 1);
    }
  TREE_VEC_ELT (awaiter_calls, 2) = awrs_call; /* await_resume().  */

  tree await_expr = build5_loc (loc, CO_AWAIT_EXPR,
				TREE_TYPE (TREE_TYPE (awrs_func)),
				a, e_proxy, o, awaiter_calls,
				build_int_cst (integer_type_node,
					       (int) suspend_kind));
  TREE_SIDE_EFFECTS (await_expr) = true;
  if (te)
    {
      TREE_OPERAND (te, 1) = await_expr;
      TREE_SIDE_EFFECTS (te) = true;
      await_expr = te;
    }
  SET_EXPR_LOCATION (await_expr, loc);
  return convert_from_reference (await_expr);
}

tree
finish_co_await_expr (location_t kw, tree expr)
{
  if (!expr || error_operand_p (expr))
    return error_mark_node;

  if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
					    "co_await"))
    return error_mark_node;

  /* The current function has now become a coroutine, if it wasn't already.  */
  DECL_COROUTINE_P (current_function_decl) = 1;

  /* This function will appear to have no return statement, even if it
     is declared to return non-void (most likely).  This is correct - we
     synthesize the return for the ramp in the compiler.  So suppress any
     extraneous warnings during substitution.  */
  suppress_warning (current_function_decl, OPT_Wreturn_type);

  /* If we don't know the promise type, we can't proceed, build the
     co_await with the expression unchanged.  */
  tree functype = TREE_TYPE (current_function_decl);
  if (dependent_type_p (functype) || type_dependent_expression_p (expr))
    {
      tree aw_expr = build5_loc (kw, CO_AWAIT_EXPR, unknown_type_node, expr,
				 NULL_TREE, NULL_TREE, NULL_TREE,
				 integer_zero_node);
      TREE_SIDE_EFFECTS (aw_expr) = true;
      return aw_expr;
    }

  /* We must be able to look up the "await_transform" method in the scope of
     the promise type, and obtain its return type.  */
  if (!coro_promise_type_found_p (current_function_decl, kw))
    return error_mark_node;

  /* [expr.await] 3.2
     The incoming cast expression might be transformed by a promise
     'await_transform()'.  */
  tree at_meth
    = lookup_promise_method (current_function_decl,
			     coro_await_transform_identifier, kw,
			     /*musthave=*/false);
  if (at_meth == error_mark_node)
    return error_mark_node;

  tree a = expr;
  if (at_meth)
    {
      /* try to build a = p.await_transform (e). */
      vec<tree, va_gc> *args = make_tree_vector_single (expr);
      a = build_new_method_call (get_coroutine_promise_proxy (
				   current_function_decl),
				 at_meth, &args, NULL_TREE, LOOKUP_NORMAL,
				 NULL, tf_warning_or_error);

      /* As I read the section.
	 We saw an await_transform method, so it's mandatory that we replace
	 expr with p.await_transform (expr), therefore if the method call fails
	 (presumably, we don't have suitable arguments) then this part of the
	 process fails.  */
      if (a == error_mark_node)
	return error_mark_node;
    }

  /* Now we want to build co_await a.  */
  return build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT);
}

/* Take the EXPR given and attempt to build:
     co_await p.yield_value (expr);
   per [expr.yield] para 1. */

tree
finish_co_yield_expr (location_t kw, tree expr)
{
  if (!expr || error_operand_p (expr))
    return error_mark_node;

  /* Check the general requirements and simple syntax errors.  */
  if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
					    "co_yield"))
    return error_mark_node;

  /* The current function has now become a coroutine, if it wasn't already.  */
  DECL_COROUTINE_P (current_function_decl) = 1;

  /* This function will appear to have no return statement, even if it
     is declared to return non-void (most likely).  This is correct - we
     synthesize the return for the ramp in the compiler.  So suppress any
     extraneous warnings during substitution.  */
  suppress_warning (current_function_decl, OPT_Wreturn_type);

  /* If we don't know the promise type, we can't proceed, build the
     co_await with the expression unchanged.  */
  tree functype = TREE_TYPE (current_function_decl);
  if (dependent_type_p (functype) || type_dependent_expression_p (expr))
    return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr, NULL_TREE);

  if (!coro_promise_type_found_p (current_function_decl, kw))
    /* We must be able to look up the "yield_value" method in the scope of
       the promise type, and obtain its return type.  */
    return error_mark_node;

  /* [expr.yield] / 1
     Let e be the operand of the yield-expression and p be an lvalue naming
     the promise object of the enclosing coroutine, then the yield-expression
     is equivalent to the expression co_await p.yield_value(e).
     build p.yield_value(e):  */
  vec<tree, va_gc> *args = make_tree_vector_single (expr);
  tree yield_call
    = coro_build_promise_expression (current_function_decl, NULL,
				     coro_yield_value_identifier, kw,
				     &args, /*musthave=*/true);
  release_tree_vector (args);

  /* Now build co_await p.yield_value (e).
     Noting that for co_yield, there is no evaluation of any potential
     promise transform_await(), so we call build_co_await directly.  */

  tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
  if (op != error_mark_node)
    {
      if (REFERENCE_REF_P (op))
	op = TREE_OPERAND (op, 0);
      /* If the await expression is wrapped in a TARGET_EXPR, then transfer
	 that wrapper to the CO_YIELD_EXPR, since this is just a proxy for
	 its contained await.  Otherwise, just build the CO_YIELD_EXPR.  */
      if (TREE_CODE (op) == TARGET_EXPR)
	{
	  tree t = TREE_OPERAND (op, 1);
	  t = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (t), expr, t);
	  TREE_OPERAND (op, 1) = t;
	}
      else
	op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
      TREE_SIDE_EFFECTS (op) = 1;
      op = convert_from_reference (op);
    }

  return op;
}

/* Check and build a co_return statement.
   First that it's valid to have a co_return keyword here.
   If it is, then check and build the p.return_{void(),value(expr)}.
   These are built against a proxy for the promise, which will be filled
   in with the actual frame version when the function is transformed.  */

tree
finish_co_return_stmt (location_t kw, tree expr)
{
  if (expr)
    STRIP_ANY_LOCATION_WRAPPER (expr);

  if (error_operand_p (expr))
    return error_mark_node;

  /* If it fails the following test, the function is not permitted to be a
     coroutine, so the co_return statement is erroneous.  */
  if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
					    "co_return"))
    return error_mark_node;

  /* The current function has now become a coroutine, if it wasn't
     already.  */
  DECL_COROUTINE_P (current_function_decl) = 1;

  /* This function will appear to have no return statement, even if it
     is declared to return non-void (most likely).  This is correct - we
     synthesize the return for the ramp in the compiler.  So suppress any
     extraneous warnings during substitution.  */
  suppress_warning (current_function_decl, OPT_Wreturn_type);

  if (processing_template_decl
      && check_for_bare_parameter_packs (expr))
    return error_mark_node;

  /* If we don't know the promise type, we can't proceed, build the
     co_return with the expression unchanged.  */
  tree functype = TREE_TYPE (current_function_decl);
  if (dependent_type_p (functype) || type_dependent_expression_p (expr))
    {
      /* co_return expressions are always void type, regardless of the
	 expression type.  */
      expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node,
			 expr, NULL_TREE);
      expr = maybe_cleanup_point_expr_void (expr);
      return add_stmt (expr);
    }

  if (!coro_promise_type_found_p (current_function_decl, kw))
    return error_mark_node;

  /* Suppress -Wreturn-type for co_return, we need to check indirectly
     whether the promise type has a suitable return_void/return_value.  */
  suppress_warning (current_function_decl, OPT_Wreturn_type);

  if (!processing_template_decl && warn_sequence_point)
    verify_sequence_points (expr);

  if (expr)
    {
      /* If we had an id-expression obfuscated by force_paren_expr, we need
	 to undo it so we can try to treat it as an rvalue below.  */
      expr = maybe_undo_parenthesized_ref (expr);

      if (processing_template_decl)
	expr = build_non_dependent_expr (expr);

      if (error_operand_p (expr))
	return error_mark_node;
    }

  /* If the promise object doesn't have the correct return call then
     there's a mis-match between the co_return <expr> and this.  */
  tree co_ret_call = error_mark_node;
  if (expr == NULL_TREE || VOID_TYPE_P (TREE_TYPE (expr)))
    co_ret_call
      = get_coroutine_return_void_expr (current_function_decl, kw, true);
  else
    {
      /* [class.copy.elision] / 3.
	 An implicitly movable entity is a variable of automatic storage
	 duration that is either a non-volatile object or an rvalue reference
	 to a non-volatile object type.  For such objects in the context of
	 the co_return, the overload resolution should be carried out first
	 treating the object as an rvalue, if that fails, then we fall back
	 to regular overload resolution.  */

      tree arg = expr;
      if (tree moved = treat_lvalue_as_rvalue_p (expr, /*return*/true))
	arg = moved;

      releasing_vec args = make_tree_vector_single (arg);
      co_ret_call
	= coro_build_promise_expression (current_function_decl, NULL,
					 coro_return_value_identifier, kw,
					 &args, /*musthave=*/true);
    }

  /* Makes no sense for a co-routine really. */
  if (TREE_THIS_VOLATILE (current_function_decl))
    warning_at (kw, 0,
		"function declared %<noreturn%> has a"
		" %<co_return%> statement");

  expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node, expr, co_ret_call);
  expr = maybe_cleanup_point_expr_void (expr);
  return add_stmt (expr);
}

/* We need to validate the arguments to __builtin_coro_promise, since the
   second two must be constant, and the builtins machinery doesn't seem to
   deal with that properly.  */

tree
coro_validate_builtin_call (tree call, tsubst_flags_t)
{
  tree fn = TREE_OPERAND (CALL_EXPR_FN (call), 0);

  gcc_checking_assert (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL);
  switch (DECL_FUNCTION_CODE (fn))
    {
    default:
      return call;

    case BUILT_IN_CORO_PROMISE:
      {
	/* Argument 0 is already checked by the normal built-in machinery
	   Argument 1 must be a constant of size type.  It probably makes
	   little sense if it's not a power of 2, but that isn't specified
	   formally.  */
	tree arg = CALL_EXPR_ARG (call, 1);
	location_t loc = EXPR_LOCATION (arg);

	/* We expect alignof expressions in templates.  */
	if (TREE_CODE (arg) == NON_DEPENDENT_EXPR
	    && TREE_CODE (TREE_OPERAND (arg, 0)) == ALIGNOF_EXPR)
	  ;
	else if (!TREE_CONSTANT (arg))
	  {
	    error_at (loc, "the align argument to %<__builtin_coro_promise%>"
			   " must be a constant");
	    return error_mark_node;
	  }
	/* Argument 2 is the direction - to / from handle address to promise
	   address.  */
	arg = CALL_EXPR_ARG (call, 2);
	loc = EXPR_LOCATION (arg);
	if (!TREE_CONSTANT (arg))
	  {
	    error_at (loc, "the direction argument to"
			   " %<__builtin_coro_promise%> must be a constant");
	    return error_mark_node;
	  }
	return call;
	break;
      }
    }
}

/* ================= Morph and Expand. =================

   The entry point here is morph_fn_to_coro () which is called from
   finish_function () when we have completed any template expansion.

   This is preceded by helper functions that implement the phases below.

   The process proceeds in four phases.

   A Initial framing.
     The user's function body is wrapped in the initial and final suspend
     points and we begin building the coroutine frame.
     We build empty decls for the actor and destroyer functions at this
     time too.
     When exceptions are enabled, the user's function body will also be
     wrapped in a try-catch block with the catch invoking the promise
     class 'unhandled_exception' method.

   B Analysis.
     The user's function body is analyzed to determine the suspend points,
     if any, and to capture local variables that might persist across such
     suspensions.  In most cases, it is not necessary to capture compiler
     temporaries, since the tree-lowering nests the suspensions correctly.
     However, in the case of a captured reference, there is a lifetime
     extension to the end of the full expression - which can mean across a
     suspend point in which case it must be promoted to a frame variable.

     At the conclusion of analysis, we have a conservative frame layout and
     maps of the local variables to their frame entry points.

   C Build the ramp function.
     Carry out the allocation for the coroutine frame (NOTE; the actual size
     computation is deferred until late in the middle end to allow for future
     optimizations that will be allowed to elide unused frame entries).
     We build the return object.

   D Build and expand the actor and destroyer function bodies.
     The destroyer is a trivial shim that sets a bit to indicate that the
     destroy dispatcher should be used and then calls into the actor.

     The actor function is the implementation of the user's state machine.
     The current suspend point is noted in an index.
     Each suspend point is encoded as a pair of internal functions, one in
     the relevant dispatcher, and one representing the suspend point.

     During this process, the user's local variables and the proxies for the
     self-handle and the promise class instance are re-written to their
     coroutine frame equivalents.

     The complete bodies for the ramp, actor and destroy function are passed
     back to finish_function for folding and gimplification.  */

/* Helpers to build EXPR_STMT and void-cast EXPR_STMT, common ops.  */

static tree
coro_build_expr_stmt (tree expr, location_t loc)
{
  return maybe_cleanup_point_expr_void (build_stmt (loc, EXPR_STMT, expr));
}

static tree
coro_build_cvt_void_expr_stmt (tree expr, location_t loc)
{
  tree t = build1 (CONVERT_EXPR, void_type_node, expr);
  return coro_build_expr_stmt (t, loc);
}

/* Helpers to build an artificial var, with location LOC, NAME and TYPE, in
   CTX, and with initializer INIT.  */

static tree
coro_build_artificial_var (location_t loc, tree name, tree type, tree ctx,
			   tree init)
{
  tree res = build_lang_decl (VAR_DECL, name, type);
  DECL_SOURCE_LOCATION (res) = loc;
  DECL_CONTEXT (res) = ctx;
  DECL_ARTIFICIAL (res) = true;
  DECL_INITIAL (res) = init;
  return res;
}

static tree
coro_build_artificial_var (location_t loc, const char *name, tree type,
			   tree ctx, tree init)
{
  return coro_build_artificial_var (loc, get_identifier (name),
				    type, ctx, init);
}

/* Helpers for label creation:
   1. Create a named label in the specified context.  */

static tree
create_anon_label_with_ctx (location_t loc, tree ctx)
{
  tree lab = build_decl (loc, LABEL_DECL, NULL_TREE, void_type_node);

  DECL_CONTEXT (lab) = ctx;
  DECL_ARTIFICIAL (lab) = true;
  DECL_IGNORED_P (lab) = true;
  TREE_USED (lab) = true;
  return lab;
}

/*  2. Create a named label in the specified context.  */

static tree
create_named_label_with_ctx (location_t loc, const char *name, tree ctx)
{
  tree lab_id = get_identifier (name);
  tree lab = define_label (loc, lab_id);
  DECL_CONTEXT (lab) = ctx;
  DECL_ARTIFICIAL (lab) = true;
  TREE_USED (lab) = true;
  return lab;
}

struct proxy_replace
{
  tree from, to;
};

static tree
replace_proxy (tree *here, int *do_subtree, void *d)
{
  proxy_replace *data = (proxy_replace *) d;

  if (*here == data->from)
    {
      *here = data->to;
      *do_subtree = 0;
    }
  else
    *do_subtree = 1;
  return NULL_TREE;
}

/* Support for expansion of co_await statements.  */

struct coro_aw_data
{
  tree actor_fn;   /* Decl for context.  */
  tree coro_fp;    /* Frame pointer var.  */
  tree resume_idx; /* This is the index var in the frame.  */
  tree i_a_r_c;    /* initial suspend await_resume() was called if true.  */
  tree self_h;     /* This is a handle to the current coro (frame var).  */
  tree cleanup;    /* This is where to go once we complete local destroy.  */
  tree cororet;    /* This is where to go if we suspend.  */
  tree corocont;   /* This is where to go if we continue.  */
  tree conthand;   /* This is the handle for a continuation.  */
  unsigned index;  /* This is our current resume index.  */
};

/* Lightweight search for the first await expression in tree-walk order.
   returns:
     The first await expression found in STMT.
     NULL_TREE if there are none.
   So can be used to determine if the statement needs to be processed for
   awaits.  */

static tree
co_await_find_in_subtree (tree *stmt, int *, void *d)
{
  tree **p = (tree **) d;
  if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
    {
      *p = stmt;
      return *stmt;
    }
  return NULL_TREE;
}

/* Starting with a statement:

   stmt => some tree containing one or more await expressions.

   We replace the statement with:
   <STATEMENT_LIST> {
      initialize awaitable
      if (!ready)
	{
	  suspension context.
	}
      resume:
	revised statement with one await expression rewritten to its
	await_resume() return value.
   }

   We then recurse into the initializer and the revised statement
   repeating this replacement until there are no more await expressions
   in either.  */

static tree *
expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
{
  coro_aw_data *data = (coro_aw_data *) d;

  tree saved_statement = *stmt;
  tree saved_co_await = *await_expr;

  tree actor = data->actor_fn;
  location_t loc = EXPR_LOCATION (*stmt);
  tree var = TREE_OPERAND (saved_co_await, 1);  /* frame slot. */
  tree expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
  tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);

  tree source = TREE_OPERAND (saved_co_await, 4);
  bool is_final = (source
		   && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
  bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
  int resume_point = data->index;
  size_t bufsize = sizeof ("destroy.") + 10;
  char *buf = (char *) alloca (bufsize);
  snprintf (buf, bufsize, "destroy.%d", resume_point);
  tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
  snprintf (buf, bufsize, "resume.%d", resume_point);
  tree resume_label = create_named_label_with_ctx (loc, buf, actor);
  tree empty_list = build_empty_stmt (loc);

  tree await_type = TREE_TYPE (var);
  tree stmt_list = NULL;
  tree r;
  tree *await_init = NULL;

  if (!expr)
    needs_dtor = false; /* No need, the var's lifetime is managed elsewhere.  */
  else
    {
      r = coro_build_cvt_void_expr_stmt (expr, loc);
      append_to_statement_list_force (r, &stmt_list);
      /* We have an initializer, which might itself contain await exprs.  */
      await_init = tsi_stmt_ptr (tsi_last (stmt_list));
    }

  /* Use the await_ready() call to test if we need to suspend.  */
  tree ready_cond = TREE_VEC_ELT (awaiter_calls, 0); /* await_ready().  */
  /* Convert to bool, if necessary.  */
  if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
    ready_cond = cp_convert (boolean_type_node, ready_cond,
			     tf_warning_or_error);
  /* Be aggressive in folding here, since there are a significant number of
     cases where the ready condition is constant.  */
  ready_cond = invert_truthvalue_loc (loc, ready_cond);
  ready_cond
    = build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, ready_cond);

  tree body_list = NULL;
  tree susp_idx = build_int_cst (short_unsigned_type_node, data->index);
  r = build2_loc (loc, MODIFY_EXPR, short_unsigned_type_node, data->resume_idx,
		  susp_idx);
  r = coro_build_cvt_void_expr_stmt (r, loc);
  append_to_statement_list (r, &body_list);

  /* Find out what we have to do with the awaiter's suspend method.
     [expr.await]
     (5.1) If the result of await-ready is false, the coroutine is considered
	   suspended. Then:
     (5.1.1) If the type of await-suspend is std::coroutine_handle<Z>,
	     await-suspend.resume() is evaluated.
     (5.1.2) if the type of await-suspend is bool, await-suspend is evaluated,
	     and the coroutine is resumed if the result is false.
     (5.1.3) Otherwise, await-suspend is evaluated.  */

  tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend().  */
  tree susp_type = TREE_TYPE (suspend);

  bool is_cont = false;
  /* NOTE: final suspend can't resume; the "resume" label in that case
     corresponds to implicit destruction.  */
  if (VOID_TYPE_P (susp_type))
    {
      /* We just call await_suspend() and hit the yield.  */
      suspend = coro_build_cvt_void_expr_stmt (suspend, loc);
      append_to_statement_list (suspend, &body_list);
    }
  else if (TREE_CODE (susp_type) == BOOLEAN_TYPE)
    {
      /* Boolean return, continue if the call returns false.  */
      suspend = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, suspend);
      suspend
	= build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, suspend);
      tree go_on = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
      r = build3_loc (loc, COND_EXPR, void_type_node, suspend, go_on,
		      empty_list);
      append_to_statement_list (r, &body_list);
    }
  else
    {
      r = build1_loc (loc, CONVERT_EXPR, void_coro_handle_type, suspend);
      r = build2_loc (loc, INIT_EXPR, void_coro_handle_type, data->conthand, r);
      r = build1 (CONVERT_EXPR, void_type_node, r);
      append_to_statement_list (r, &body_list);
      is_cont = true;
    }

  tree d_l = build_address (destroy_label);
  tree r_l = build_address (resume_label);
  tree susp = build_address (data->cororet);
  tree cont = build_address (data->corocont);
  tree final_susp = build_int_cst (integer_type_node, is_final ? 1 : 0);

  susp_idx = build_int_cst (integer_type_node, data->index);

  tree sw = begin_switch_stmt ();
  tree cond = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
  DECL_ARTIFICIAL (cond) = 1;
  DECL_IGNORED_P (cond) = 1;
  layout_decl (cond, 0);

  r = build_call_expr_internal_loc (loc, IFN_CO_YIELD, integer_type_node, 5,
				    susp_idx, final_susp, r_l, d_l,
				    data->coro_fp);
  r = build2 (INIT_EXPR, integer_type_node, cond, r);
  finish_switch_cond (r, sw);
  r = build_case_label (build_int_cst (integer_type_node, 0), NULL_TREE,
			create_anon_label_with_ctx (loc, actor));
  add_stmt (r); /* case 0: */
  /* Implement the suspend, a scope exit without clean ups.  */
  r = build_call_expr_internal_loc (loc, IFN_CO_SUSPN, void_type_node, 1,
				    is_cont ? cont : susp);
  r = coro_build_cvt_void_expr_stmt (r, loc);
  add_stmt (r); /*   goto ret;  */
  r = build_case_label (build_int_cst (integer_type_node, 1), NULL_TREE,
			create_anon_label_with_ctx (loc, actor));
  add_stmt (r); /* case 1:  */
  r = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
  add_stmt (r); /*  goto resume;  */
  r = build_case_label (NULL_TREE, NULL_TREE,
			create_anon_label_with_ctx (loc, actor));
  add_stmt (r); /* default:;  */
  r = build1_loc (loc, GOTO_EXPR, void_type_node, destroy_label);
  add_stmt (r); /* goto destroy;  */

  /* part of finish switch.  */
  SWITCH_STMT_BODY (sw) = pop_stmt_list (SWITCH_STMT_BODY (sw));
  pop_switch ();
  tree scope = SWITCH_STMT_SCOPE (sw);
  SWITCH_STMT_SCOPE (sw) = NULL;
  r = do_poplevel (scope);
  append_to_statement_list (r, &body_list);

  destroy_label = build_stmt (loc, LABEL_EXPR, destroy_label);
  append_to_statement_list (destroy_label, &body_list);
  if (needs_dtor)
    {
      tree dtor = build_special_member_call (var, complete_dtor_identifier,
					     NULL, await_type, LOOKUP_NORMAL,
					     tf_warning_or_error);
      append_to_statement_list (dtor, &body_list);
    }
  r = build1_loc (loc, GOTO_EXPR, void_type_node, data->cleanup);
  append_to_statement_list (r, &body_list);

  r = build3_loc (loc, COND_EXPR, void_type_node, ready_cond, body_list,
		  empty_list);

  append_to_statement_list (r, &stmt_list);

  /* Resume point.  */
  resume_label = build_stmt (loc, LABEL_EXPR, resume_label);
  append_to_statement_list (resume_label, &stmt_list);

  /* This will produce the value (if one is provided) from the co_await
     expression.  */
  tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume().  */
  if (REFERENCE_REF_P (resume_call))
    /* Sink to await_resume call_expr.  */
    resume_call = TREE_OPERAND (resume_call, 0);

  *await_expr = resume_call; /* Replace the co_await expr with its result.  */
  append_to_statement_list_force (saved_statement, &stmt_list);
  /* Get a pointer to the revised statement.  */
  tree *revised = tsi_stmt_ptr (tsi_last (stmt_list));
  if (needs_dtor)
    {
      tree dtor = build_special_member_call (var, complete_dtor_identifier,
					     NULL, await_type, LOOKUP_NORMAL,
					     tf_warning_or_error);
      append_to_statement_list (dtor, &stmt_list);
    }
  data->index += 2;

  /* Replace the original statement with the expansion.  */
  *stmt = stmt_list;

  /* Now, if the awaitable had an initializer, expand any awaits that might
     be embedded in it.  */
  tree *aw_expr_ptr;
  if (await_init &&
      cp_walk_tree (await_init, co_await_find_in_subtree, &aw_expr_ptr, NULL))
    expand_one_await_expression (await_init, aw_expr_ptr, d);

  /* Expand any more await expressions in the original statement.  */
  if (cp_walk_tree (revised, co_await_find_in_subtree, &aw_expr_ptr, NULL))
    expand_one_await_expression (revised, aw_expr_ptr, d);

  return NULL;
}

/* Check to see if a statement contains at least one await expression, if
   so, then process that.  */

static tree
process_one_statement (tree *stmt, void *d)
{
  tree *aw_expr_ptr;
  if (cp_walk_tree (stmt, co_await_find_in_subtree, &aw_expr_ptr, NULL))
    expand_one_await_expression (stmt, aw_expr_ptr, d);
  return NULL_TREE;
}

static tree
await_statement_expander (tree *stmt, int *do_subtree, void *d)
{
  tree res = NULL_TREE;

  /* Process a statement at a time.  */
  if (STATEMENT_CLASS_P (*stmt) || TREE_CODE (*stmt) == BIND_EXPR)
    return NULL_TREE; /* Just process the sub-trees.  */
  else if (TREE_CODE (*stmt) == STATEMENT_LIST)
    {
      for (tree &s : tsi_range (*stmt))
	{
	  res = cp_walk_tree (&s, await_statement_expander,
			      d, NULL);
	  if (res)
	    return res;
	}
      *do_subtree = 0; /* Done subtrees.  */
    }
  else if (EXPR_P (*stmt))
    {
      process_one_statement (stmt, d);
      *do_subtree = 0; /* Done subtrees.  */
    }

  /* Continue statement walk, where required.  */
  return res;
}

/* Suspend point hash_map.  */

struct suspend_point_info
{
  /* coro frame field type.  */
  tree awaitable_type;
  /* coro frame field name.  */
  tree await_field_id;
};

static hash_map<tree, suspend_point_info> *suspend_points;

struct await_xform_data
{
  tree actor_fn;   /* Decl for context.  */
  tree actor_frame;
};

/* When we built the await expressions, we didn't know the coro frame
   layout, therefore no idea where to find the promise or where to put
   the awaitables.  Now we know these things, fill them in.  */

static tree
transform_await_expr (tree await_expr, await_xform_data *xform)
{
  suspend_point_info *si = suspend_points->get (await_expr);
  location_t loc = EXPR_LOCATION (await_expr);
  if (!si)
    {
      error_at (loc, "no suspend point info for %qD", await_expr);
      return error_mark_node;
    }

  /* So, on entry, we have:
     in : CO_AWAIT_EXPR (a, e_proxy, o, awr_call_vector, mode)
	  We no longer need a [it had diagnostic value, maybe?]
	  We need to replace the e_proxy in the awr_call.  */

  tree coro_frame_type = TREE_TYPE (xform->actor_frame);

  /* If we have a frame var for the awaitable, get a reference to it.  */
  proxy_replace data;
  if (si->await_field_id)
    {
      tree as_m
	 = lookup_member (coro_frame_type, si->await_field_id,
			  /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
      tree as = build_class_member_access_expr (xform->actor_frame, as_m,
						NULL_TREE, true,
						tf_warning_or_error);

      /* Replace references to the instance proxy with the frame entry now
	 computed.  */
      data.from = TREE_OPERAND (await_expr, 1);
      data.to = as;
      cp_walk_tree (&await_expr, replace_proxy, &data, NULL);

      /* .. and replace.  */
      TREE_OPERAND (await_expr, 1) = as;
    }

  return await_expr;
}

/* A wrapper for the transform_await_expr function so that it can be a
   callback from cp_walk_tree.  */

static tree
transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
{
  /* Set actor function as new DECL_CONTEXT of label_decl.  */
  struct await_xform_data *xform = (struct await_xform_data *) d;
  if (TREE_CODE (*stmt) == LABEL_DECL
      && DECL_CONTEXT (*stmt) != xform->actor_fn)
    DECL_CONTEXT (*stmt) = xform->actor_fn;

  /* We should have already lowered co_yields to their co_await.  */
  gcc_checking_assert (TREE_CODE (*stmt) != CO_YIELD_EXPR);
  if (TREE_CODE (*stmt) != CO_AWAIT_EXPR)
    return NULL_TREE;

  tree await_expr = *stmt;
  *stmt = transform_await_expr (await_expr, xform);
  if (*stmt == error_mark_node)
    *do_subtree = 0;
  return NULL_TREE;
}

/* This caches information that we determine about function params,
   their uses and copies in the coroutine frame.  */

struct param_info
{
  tree field_id;     /* The name of the copy in the coroutine frame.  */
  tree copy_var;     /* The local var proxy for the frame copy.  */
  vec<tree *> *body_uses; /* Worklist of uses, void if there are none.  */
  tree frame_type;   /* The type used to represent this parm in the frame.  */
  tree orig_type;    /* The original type of the parm (not as passed).  */
  tree guard_var;    /* If we need a DTOR on exception, this bool guards it.  */
  tree fr_copy_dtor; /* If we need a DTOR on exception, this is it.  */
  bool by_ref;       /* Was passed by reference.  */
  bool pt_ref;       /* Was a pointer to object.  */
  bool rv_ref;       /* Was an rvalue ref.  */
  bool trivial_dtor; /* The frame type has a trivial DTOR.  */
  bool this_ptr;     /* Is 'this' */
  bool lambda_cobj;  /* Lambda capture object */
};

struct local_var_info
{
  tree field_id;
  tree field_idx;
  tree frame_type;
  bool is_lambda_capture;
  bool is_static;
  bool has_value_expr_p;
  location_t def_loc;
};

/* For figuring out what local variable usage we have.  */
struct local_vars_transform
{
  tree context;
  tree actor_frame;
  tree coro_frame_type;
  location_t loc;
  hash_map<tree, local_var_info> *local_var_uses;
};

static tree
transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
{
  local_vars_transform *lvd = (local_vars_transform *) d;

  /* For each var in this bind expr (that has a frame id, which means it was
     accessed), build a frame reference and add it as the DECL_VALUE_EXPR.  */

  if (TREE_CODE (*stmt) == BIND_EXPR)
    {
      tree lvar;
      for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
	   lvar = DECL_CHAIN (lvar))
	{
	  bool existed;
	  local_var_info &local_var
	    = lvd->local_var_uses->get_or_insert (lvar, &existed);
	  gcc_checking_assert (existed);

	  /* Re-write the variable's context to be in the actor func.  */
	  DECL_CONTEXT (lvar) = lvd->context;

	  /* For capture proxies, this could include the decl value expr.  */
	  if (local_var.is_lambda_capture || local_var.has_value_expr_p)
	    continue; /* No frame entry for this.  */

	  /* TODO: implement selective generation of fields when vars are
	     known not-used.  */
	  if (local_var.field_id == NULL_TREE)
	    continue; /* Wasn't used.  */

	  tree fld_ref
	    = lookup_member (lvd->coro_frame_type, local_var.field_id,
			     /*protect=*/1, /*want_type=*/0,
			     tf_warning_or_error);
	  tree fld_idx = build3_loc (lvd->loc, COMPONENT_REF, TREE_TYPE (lvar),
				     lvd->actor_frame, fld_ref, NULL_TREE);
	  local_var.field_idx = fld_idx;
	  SET_DECL_VALUE_EXPR (lvar, fld_idx);
	  DECL_HAS_VALUE_EXPR_P (lvar) = true;
	}
      cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
      *do_subtree = 0; /* We've done the body already.  */
      return NULL_TREE;
    }
  return NULL_TREE;
}

/* A helper to build the frame DTOR.
   [dcl.fct.def.coroutine] / 12
   The deallocation function’s name is looked up in the scope of the promise
   type.  If this lookup fails, the deallocation function’s name is looked up
   in the global scope.  If deallocation function lookup finds both a usual
   deallocation function with only a pointer parameter and a usual
   deallocation function with both a pointer parameter and a size parameter,
   then the selected deallocation function shall be the one with two
   parameters.  Otherwise, the selected deallocation function shall be the
   function with one parameter.  If no usual deallocation function is found
   the program is ill-formed.  The selected deallocation function shall be
   called with the address of the block of storage to be reclaimed as its
   first argument.  If a deallocation function with a parameter of type
   std::size_t is used, the size of the block is passed as the corresponding
   argument.  */

static tree
coro_get_frame_dtor (tree coro_fp, tree orig, tree frame_size,
		     tree promise_type, location_t loc)
{
  tree del_coro_fr = NULL_TREE;
  tree frame_arg = build1 (CONVERT_EXPR, ptr_type_node, coro_fp);
  tree delname = ovl_op_identifier (false, DELETE_EXPR);
  tree fns = lookup_promise_method (orig, delname, loc,
					/*musthave=*/false);
  if (fns && BASELINK_P (fns))
    {
      /* Look for sized version first, since this takes precedence.  */
      vec<tree, va_gc> *args = make_tree_vector ();
      vec_safe_push (args, frame_arg);
      vec_safe_push (args, frame_size);
      tree dummy_promise = build_dummy_object (promise_type);

      /* It's OK to fail for this one... */
      del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
					   NULL_TREE, LOOKUP_NORMAL, NULL,
					   tf_none);

      if (!del_coro_fr || del_coro_fr == error_mark_node)
	{
	  release_tree_vector (args);
	  args = make_tree_vector_single (frame_arg);
	  del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
					       NULL_TREE, LOOKUP_NORMAL, NULL,
					       tf_none);
	}

      /* But one of them must succeed, or the program is ill-formed.  */
      if (!del_coro_fr || del_coro_fr == error_mark_node)
	{
	  error_at (loc, "%qE is provided by %qT but is not usable with"
		  " the function signature %qD", delname, promise_type, orig);
	  del_coro_fr = error_mark_node;
	}
    }
  else
    {
      del_coro_fr = build_op_delete_call (DELETE_EXPR, frame_arg, frame_size,
					  /*global_p=*/true, /*placement=*/NULL,
					  /*alloc_fn=*/NULL,
					  tf_warning_or_error);
      if (!del_coro_fr || del_coro_fr == error_mark_node)
	del_coro_fr = error_mark_node;
    }
  return del_coro_fr;
}

/* The actor transform.  */

static void
build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
		tree orig, hash_map<tree, local_var_info> *local_var_uses,
		vec<tree, va_gc> *param_dtor_list,
		tree resume_idx_var, unsigned body_count, tree frame_size)
{
  verify_stmt_tree (fnbody);
  /* Some things we inherit from the original function.  */
  tree handle_type = get_coroutine_handle_type (orig);
  tree promise_type = get_coroutine_promise_type (orig);
  tree promise_proxy = get_coroutine_promise_proxy (orig);

  /* One param, the coro frame pointer.  */
  tree actor_fp = DECL_ARGUMENTS (actor);

  /* We have a definition here.  */
  TREE_STATIC (actor) = 1;

  tree actor_outer = push_stmt_list ();
  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
  tree stmt = begin_compound_stmt (BCS_FN_BODY);

  tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
  tree top_block = make_node (BLOCK);
  BIND_EXPR_BLOCK (actor_bind) = top_block;

  tree continuation = coro_build_artificial_var (loc, coro_actor_continue_id,
						 void_coro_handle_type, actor,
						 NULL_TREE);

  BIND_EXPR_VARS (actor_bind) = continuation;
  BLOCK_VARS (top_block) = BIND_EXPR_VARS (actor_bind) ;

  /* Link in the block associated with the outer scope of the re-written
     function body.  */
  tree first = expr_first (fnbody);
  gcc_checking_assert (first && TREE_CODE (first) == BIND_EXPR);
  tree block = BIND_EXPR_BLOCK (first);
  gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
  gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE);
  BLOCK_SUPERCONTEXT (block) = top_block;
  BLOCK_SUBBLOCKS (top_block) = block;

  add_stmt (actor_bind);
  tree actor_body = push_stmt_list ();

  /* The entry point for the actor code from the ramp.  */
  tree actor_begin_label
    = create_named_label_with_ctx (loc, "actor.begin", actor);
  tree actor_frame = build1_loc (loc, INDIRECT_REF, coro_frame_type, actor_fp);

  /* Declare the continuation handle.  */
  add_decl_expr (continuation);

  /* Re-write local vars, similarly.  */
  local_vars_transform xform_vars_data
    = {actor, actor_frame, coro_frame_type, loc, local_var_uses};
  cp_walk_tree (&fnbody, transform_local_var_uses, &xform_vars_data, NULL);

  tree rat_field = lookup_member (coro_frame_type, coro_resume_index_id,
				  1, 0, tf_warning_or_error);
  tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, actor_frame,
		     rat_field, NULL_TREE);

  tree ret_label
    = create_named_label_with_ctx (loc, "actor.suspend.ret", actor);

  tree continue_label
    = create_named_label_with_ctx (loc, "actor.continue.ret", actor);

  tree lsb_if = begin_if_stmt ();
  tree chkb0 = build2 (BIT_AND_EXPR, short_unsigned_type_node, rat,
		       build_int_cst (short_unsigned_type_node, 1));
  chkb0 = build2 (NE_EXPR, short_unsigned_type_node, chkb0,
		  build_int_cst (short_unsigned_type_node, 0));
  finish_if_stmt_cond (chkb0, lsb_if);

  tree destroy_dispatcher = begin_switch_stmt ();
  finish_switch_cond (rat, destroy_dispatcher);
  tree ddeflab = build_case_label (NULL_TREE, NULL_TREE,
				   create_anon_label_with_ctx (loc, actor));
  add_stmt (ddeflab);
  tree b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
  b = coro_build_cvt_void_expr_stmt (b, loc);
  add_stmt (b);

  /* The destroy point numbered #1 is special, in that it is reached from a
     coroutine that is suspended after re-throwing from unhandled_exception().
     This label just invokes the cleanup of promise, param copies and the
     frame itself.  */
  tree del_promise_label
    = create_named_label_with_ctx (loc, "coro.delete.promise", actor);
  b = build_case_label (build_int_cst (short_unsigned_type_node, 1), NULL_TREE,
			create_anon_label_with_ctx (loc, actor));
  add_stmt (b);
  add_stmt (build_stmt (loc, GOTO_EXPR, del_promise_label));

  short unsigned lab_num = 3;
  for (unsigned destr_pt = 0; destr_pt < body_count; destr_pt++)
    {
      tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
      b = build_case_label (l_num, NULL_TREE,
			    create_anon_label_with_ctx (loc, actor));
      add_stmt (b);
      b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
					l_num);
      b = coro_build_cvt_void_expr_stmt (b, loc);
      add_stmt (b);
      b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (ddeflab));
      add_stmt (b);
      lab_num += 2;
    }

  /* Insert the prototype dispatcher.  */
  finish_switch_stmt (destroy_dispatcher);

  finish_then_clause (lsb_if);
  begin_else_clause (lsb_if);

  tree dispatcher = begin_switch_stmt ();
  finish_switch_cond (rat, dispatcher);
  b = build_case_label (build_int_cst (short_unsigned_type_node, 0), NULL_TREE,
			create_anon_label_with_ctx (loc, actor));
  add_stmt (b);
  b = build1 (GOTO_EXPR, void_type_node, actor_begin_label);
  add_stmt (b);

  tree rdeflab = build_case_label (NULL_TREE, NULL_TREE,
				   create_anon_label_with_ctx (loc, actor));
  add_stmt (rdeflab);
  b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
  b = coro_build_cvt_void_expr_stmt (b, loc);
  add_stmt (b);

  lab_num = 2;
  /* The final resume should be made to hit the default (trap, UB) entry
     although it will be unreachable via the normal entry point, since that
     is set to NULL on reaching final suspend.  */
  for (unsigned resu_pt = 0; resu_pt < body_count; resu_pt++)
    {
      tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
      b = build_case_label (l_num, NULL_TREE,
			    create_anon_label_with_ctx (loc, actor));
      add_stmt (b);
      b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
					l_num);
      b = coro_build_cvt_void_expr_stmt (b, loc);
      add_stmt (b);
      b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (rdeflab));
      add_stmt (b);
      lab_num += 2;
    }

  /* Insert the prototype dispatcher.  */
  finish_switch_stmt (dispatcher);
  finish_else_clause (lsb_if);

  finish_if_stmt (lsb_if);

  tree r = build_stmt (loc, LABEL_EXPR, actor_begin_label);
  add_stmt (r);

  /* actor's coroutine 'self handle'.  */
  tree ash_m = lookup_member (coro_frame_type, coro_self_handle_id, 1,
			      0, tf_warning_or_error);
  tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
					     false, tf_warning_or_error);
  /* So construct the self-handle from the frame address.  */
  tree hfa_m = lookup_member (handle_type, coro_from_address_identifier, 1,
			      0, tf_warning_or_error);

  r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
  vec<tree, va_gc> *args = make_tree_vector_single (r);
  tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
				    NULL, tf_warning_or_error);
  r = build2 (INIT_EXPR, handle_type, ash, hfa);
  r = coro_build_cvt_void_expr_stmt (r, loc);
  add_stmt (r);
  release_tree_vector (args);

  /* Now we know the real promise, and enough about the frame layout to
     decide where to put things.  */

  await_xform_data xform = {actor, actor_frame};

  /* Transform the await expressions in the function body.  Only do each
     await tree once!  */
  hash_set<tree> pset;
  cp_walk_tree (&fnbody, transform_await_wrapper, &xform, &pset);

  /* Add in our function body with the co_returns rewritten to final form.  */
  add_stmt (fnbody);

  /* now do the tail of the function.  */
  r = build_stmt (loc, LABEL_EXPR, del_promise_label);
  add_stmt (r);

  /* Destructors for the things we built explicitly.  */
  r = build_special_member_call (promise_proxy, complete_dtor_identifier, NULL,
				 promise_type, LOOKUP_NORMAL,
				 tf_warning_or_error);
  add_stmt (r);

  tree del_frame_label
    = create_named_label_with_ctx (loc, "coro.delete.frame", actor);
  r = build_stmt (loc, LABEL_EXPR, del_frame_label);
  add_stmt (r);

  /* Here deallocate the frame (if we allocated it), which we will have at
     present.  */
  tree fnf_m
    = lookup_member (coro_frame_type, coro_frame_needs_free_id, 1,
		     0, tf_warning_or_error);
  tree fnf2_x = build_class_member_access_expr (actor_frame, fnf_m, NULL_TREE,
						false, tf_warning_or_error);

  tree need_free_if = begin_if_stmt ();
  fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x);
  tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node);
  finish_if_stmt_cond (cmp, need_free_if);
  if (param_dtor_list != NULL)
    {
      int i;
      tree pid;
      FOR_EACH_VEC_ELT (*param_dtor_list, i, pid)
	{
	  tree m
	    = lookup_member (coro_frame_type, pid, 1, 0, tf_warning_or_error);
	  tree a = build_class_member_access_expr (actor_frame, m, NULL_TREE,
						   false, tf_warning_or_error);
	  tree t = TREE_TYPE (a);
	  tree dtor;
	  dtor
	    = build_special_member_call (a, complete_dtor_identifier, NULL, t,
					 LOOKUP_NORMAL, tf_warning_or_error);
	  add_stmt (dtor);
	}
    }

  /* Build the frame DTOR.  */
  tree del_coro_fr = coro_get_frame_dtor (actor_fp, orig, frame_size,
					  promise_type, loc);
  finish_expr_stmt (del_coro_fr);
  finish_then_clause (need_free_if);
  tree scope = IF_SCOPE (need_free_if);
  IF_SCOPE (need_free_if) = NULL;
  r = do_poplevel (scope);
  add_stmt (r);

  /* done.  */
  r = build_stmt (loc, RETURN_EXPR, NULL);
  suppress_warning (r); /* We don't want a warning about this.  */
  r = maybe_cleanup_point_expr_void (r);
  add_stmt (r);

  /* This is the suspend return point.  */
  r = build_stmt (loc, LABEL_EXPR, ret_label);
  add_stmt (r);

  r = build_stmt (loc, RETURN_EXPR, NULL);
  suppress_warning (r); /* We don't want a warning about this.  */
  r = maybe_cleanup_point_expr_void (r);
  add_stmt (r);

  /* This is the 'continuation' return point.  For such a case we have a coro
     handle (from the await_suspend() call) and we want handle.resume() to
     execute as a tailcall allowing arbitrary chaining of coroutines.  */
  r = build_stmt (loc, LABEL_EXPR, continue_label);
  add_stmt (r);

  /* We want to force a tail-call even for O0/1, so this expands the resume
     call into its underlying implementation.  */
  tree addr = lookup_member (void_coro_handle_type, coro_address_identifier,
			       1, 0, tf_warning_or_error);
  addr = build_new_method_call (continuation, addr, NULL, NULL_TREE,
				  LOOKUP_NORMAL, NULL, tf_warning_or_error);
  tree resume = build_call_expr_loc
    (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);

  /* In order to support an arbitrary number of coroutine continuations,
     we must tail call them.  However, some targets do not support indirect
     tail calls to arbitrary callees.  See PR94359.  */
  CALL_EXPR_TAILCALL (resume) = true;
  resume = coro_build_cvt_void_expr_stmt (resume, loc);
  add_stmt (resume);

  r = build_stmt (loc, RETURN_EXPR, NULL);
  gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
  add_stmt (r);

  /* We've now rewritten the tree and added the initial and final
     co_awaits.  Now pass over the tree and expand the co_awaits.  */

  coro_aw_data data = {actor, actor_fp, resume_idx_var, NULL_TREE,
		       ash, del_promise_label, ret_label,
		       continue_label, continuation, 2};
  cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);

  BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
  TREE_SIDE_EFFECTS (actor_bind) = true;

  finish_compound_stmt (stmt);
  DECL_SAVED_TREE (actor) = pop_stmt_list (actor_outer);
  verify_stmt_tree (DECL_SAVED_TREE (actor));
}

/* The prototype 'destroy' function :
   frame->__Coro_resume_index |= 1;
   actor (frame);  */

static void
build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
		  tree actor)
{
  /* One param, the coro frame pointer.  */
  tree destr_fp = DECL_ARGUMENTS (destroy);

  /* We have a definition here.  */
  TREE_STATIC (destroy) = 1;

  tree destr_outer = push_stmt_list ();
  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
  tree dstr_stmt = begin_compound_stmt (BCS_FN_BODY);

  tree destr_frame = build1 (INDIRECT_REF, coro_frame_type, destr_fp);

  tree rat_field = lookup_member (coro_frame_type, coro_resume_index_id,
				  1, 0, tf_warning_or_error);
  tree rat = build3 (COMPONENT_REF, short_unsigned_type_node,
			 destr_frame, rat_field, NULL_TREE);

  /* _resume_at |= 1 */
  tree dstr_idx = build2 (BIT_IOR_EXPR, short_unsigned_type_node, rat,
			  build_int_cst (short_unsigned_type_node, 1));
  tree r = build2 (MODIFY_EXPR, short_unsigned_type_node, rat, dstr_idx);
  r = coro_build_cvt_void_expr_stmt (r, loc);
  add_stmt (r);

  /* So .. call the actor ..  */
  r = build_call_expr_loc (loc, actor, 1, destr_fp);
  r = coro_build_cvt_void_expr_stmt (r, loc);
  add_stmt (r);

  /* done. */
  r = build_stmt (loc, RETURN_EXPR, NULL);
  r = maybe_cleanup_point_expr_void (r);
  add_stmt (r);

  finish_compound_stmt (dstr_stmt);
  DECL_SAVED_TREE (destroy) = pop_stmt_list (destr_outer);
}

/* Helper that returns an identifier for an appended extension to the
   current un-mangled function name.  */

static tree
get_fn_local_identifier (tree orig, const char *append)
{
  /* Figure out the bits we need to generate names for the outlined things
     For consistency, this needs to behave the same way as
     ASM_FORMAT_PRIVATE_NAME does. */
  tree nm = DECL_NAME (orig);
  const char *sep, *pfx = "";
#ifndef NO_DOT_IN_LABEL
  sep = ".";
#else
#ifndef NO_DOLLAR_IN_LABEL
  sep = "$";
#else
  sep = "_";
  pfx = "__";
#endif
#endif

  char *an;
  if (DECL_ASSEMBLER_NAME (orig))
    an = ACONCAT ((IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig)), sep, append,
		   (char *) 0));
  else if (DECL_USE_TEMPLATE (orig) && DECL_TEMPLATE_INFO (orig)
	   && DECL_TI_ARGS (orig))
    {
      tree tpl_args = DECL_TI_ARGS (orig);
      an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), (char *) 0));
      for (int i = 0; i < TREE_VEC_LENGTH (tpl_args); ++i)
	{
	  tree typ = DECL_NAME (TYPE_NAME (TREE_VEC_ELT (tpl_args, i)));
	  an = ACONCAT ((an, sep, IDENTIFIER_POINTER (typ), (char *) 0));
	}
      an = ACONCAT ((an, sep, append, (char *) 0));
    }
  else
    an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), sep, append, (char *) 0));

  return get_identifier (an);
}

/* Build an initial or final await initialized from the promise
   initial_suspend or final_suspend expression.  */

static tree
build_init_or_final_await (location_t loc, bool is_final)
{
  tree suspend_alt = is_final ? coro_final_suspend_identifier
			      : coro_initial_suspend_identifier;

  tree setup_call
    = coro_build_promise_expression (current_function_decl, NULL, suspend_alt,
				     loc, NULL, /*musthave=*/true);

  /* Check for noexcept on the final_suspend call.  */
  if (flag_exceptions && is_final && setup_call != error_mark_node
      && coro_diagnose_throwing_final_aw_expr (setup_call))
    return error_mark_node;

  /* So build the co_await for this */
  /* For initial/final suspends the call is "a" per [expr.await] 3.2.  */
  return build_co_await (loc, setup_call, (is_final ? FINAL_SUSPEND_POINT
						    : INITIAL_SUSPEND_POINT));
}

/* Callback to record the essential data for each await point found in the
   function.  */

static bool
register_await_info (tree await_expr, tree aw_type, tree aw_nam)
{
  bool seen;
  suspend_point_info &s
    = suspend_points->get_or_insert (await_expr, &seen);
  if (seen)
    {
      warning_at (EXPR_LOCATION (await_expr), 0, "duplicate info for %qE",
		await_expr);
      return false;
    }
  s.awaitable_type = aw_type;
  s.await_field_id = aw_nam;
  return true;
}

/* This data set is used when analyzing statements for await expressions.  */

struct susp_frame_data
{
  /* Function-wide.  */
  tree *field_list; /* The current coroutine frame field list.  */
  tree handle_type; /* The self-handle type for this coroutine.  */
  tree fs_label;    /* The destination for co_returns.  */
  vec<tree, va_gc> *block_stack; /* Track block scopes.  */
  vec<tree, va_gc> *bind_stack;  /* Track current bind expr.  */
  unsigned await_number;	 /* Which await in the function.  */
  unsigned cond_number;		 /* Which replaced condition in the fn.  */
  /* Temporary values for one statement or expression being analyzed.  */
  hash_set<tree> captured_temps; /* The suspend captured these temps.  */
  vec<tree, va_gc> *to_replace;  /* The VAR decls to replace.  */
  hash_set<tree> *truth_aoif_to_expand; /* The set of TRUTH exprs to expand.  */
  unsigned saw_awaits;		 /* Count of awaits in this statement  */
  bool captures_temporary;	 /* This expr captures temps by ref.  */
  bool needs_truth_if_exp;	 /* We must expand a truth_if expression.  */
  bool has_awaiter_init;	 /* We must handle initializing an awaiter.  */
};

/* If this is an await expression, then count it (both uniquely within the
   function and locally within a single statement).  */

static tree
register_awaits (tree *stmt, int *, void *d)
{
  tree aw_expr = *stmt;

  /* We should have already lowered co_yields to their co_await.  */
  gcc_checking_assert (TREE_CODE (aw_expr) != CO_YIELD_EXPR);

  if (TREE_CODE (aw_expr) != CO_AWAIT_EXPR)
    return NULL_TREE;

  /* Count how many awaits the current expression contains.  */
  susp_frame_data *data = (susp_frame_data *) d;
  data->saw_awaits++;
  /* Each await suspend context is unique, this is a function-wide value.  */
  data->await_number++;

  /* Awaitables should either be user-locals or promoted to coroutine frame
     entries at this point, and their initializers should have been broken
     out.  */
  tree aw = TREE_OPERAND (aw_expr, 1);
  gcc_checking_assert (!TREE_OPERAND (aw_expr, 2));

  tree aw_field_type = TREE_TYPE (aw);
  tree aw_field_nam = NULL_TREE;
  register_await_info (aw_expr, aw_field_type, aw_field_nam);

  /* Rewrite target expressions on the await_suspend () to remove extraneous
     cleanups for the awaitables, which are now promoted to frame vars and
     managed via that.  */
  tree v = TREE_OPERAND (aw_expr, 3);
  tree o = TREE_VEC_ELT (v, 1);
  if (TREE_CODE (o) == TARGET_EXPR)
    TREE_VEC_ELT (v, 1) = get_target_expr (TREE_OPERAND (o, 1));
  return NULL_TREE;
}

/* There are cases where any await expression is relevant.  */
static tree
find_any_await (tree *stmt, int *dosub, void *d)
{
  if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
    {
      *dosub = 0; /* We don't need to consider this any further.  */
      tree **p = (tree **) d;
      *p = stmt;
      return *stmt;
    }
  return NULL_TREE;
}

static bool
tmp_target_expr_p (tree t)
{
  if (TREE_CODE (t) != TARGET_EXPR)
    return false;
  tree v = TREE_OPERAND (t, 0);
  if (!DECL_ARTIFICIAL (v))
    return false;
  if (DECL_NAME (v))
    return false;
  return true;
}

/* Structure to record sub-expressions that need to be handled by the
   statement flattener.  */

struct coro_interesting_subtree
{
  tree* entry;
  hash_set<tree> *temps_used;
};

/* tree-walk callback that returns the first encountered sub-expression of
   a kind that needs to be handled specifically by the statement flattener.  */

static tree
find_interesting_subtree (tree *expr_p, int *dosub, void *d)
{
  tree expr = *expr_p;
  coro_interesting_subtree *p = (coro_interesting_subtree *)d;
  if (TREE_CODE (expr) == CO_AWAIT_EXPR)
    {
      *dosub = 0; /* We don't need to consider this any further.  */
      if (TREE_OPERAND (expr, 2))
	{
	  p->entry = expr_p;
	  return expr;
	}
    }
  else if (tmp_target_expr_p (expr)
	   && !p->temps_used->contains (expr))
    {
      p->entry = expr_p;
      return expr;
    }

  return NULL_TREE;
}

/* Node for a doubly-linked list of promoted variables and their
   initializers.  When the initializer is a conditional expression
   the 'then' and 'else' clauses are represented by a linked list
   attached to then_cl and else_cl respectively.  */

struct var_nest_node
{
  var_nest_node () = default;
  var_nest_node (tree v, tree i, var_nest_node *p, var_nest_node *n)
    : var(v), init(i), prev(p), next(n), then_cl (NULL), else_cl (NULL)
    {
      if (p)
	p->next = this;
      if (n)
	n->prev = this;
    }
  tree var;
  tree init;
  var_nest_node *prev;
  var_nest_node *next;
  var_nest_node *then_cl;
  var_nest_node *else_cl;
};

/* This is called for single statements from the co-await statement walker.
   It checks to see if the statement contains any initializers for awaitables
   and if any of these capture items by reference.  */

static void
flatten_await_stmt (var_nest_node *n, hash_set<tree> *promoted,
		    hash_set<tree> *temps_used, tree *replace_in)
{
  bool init_expr = false;
  switch (TREE_CODE (n->init))
    {
      default: break;
      /* Compound expressions must be flattened specifically.  */
      case COMPOUND_EXPR:
	{
	  tree first = TREE_OPERAND (n->init, 0);
	  n->init = TREE_OPERAND (n->init, 1);
	  var_nest_node *ins
	    = new var_nest_node(NULL_TREE, first, n->prev, n);
	  /* The compiler (but not the user) can generate temporaries with
	     uses in the second arm of a compound expr.  */
	  flatten_await_stmt (ins, promoted, temps_used, &n->init);
	  flatten_await_stmt (n, promoted, temps_used, NULL);
	  /* The two arms have been processed separately.  */
	  return;
	}
	break;
      /* Handle conditional expressions.  */
      case INIT_EXPR:
	init_expr = true;
	/* FALLTHROUGH */
      case MODIFY_EXPR:
	{
	  tree old_expr = TREE_OPERAND (n->init, 1);
	  if (TREE_CODE (old_expr) == COMPOUND_EXPR)
	    {
	      tree first = TREE_OPERAND (old_expr, 0);
	      TREE_OPERAND (n->init, 1) = TREE_OPERAND (old_expr, 1);
	      var_nest_node *ins
		= new var_nest_node(NULL_TREE, first, n->prev, n);
	      flatten_await_stmt (ins, promoted, temps_used,
				  &TREE_OPERAND (n->init, 1));
	      flatten_await_stmt (n, promoted, temps_used, NULL);
	      return;
	    }
	  if (TREE_CODE (old_expr) != COND_EXPR)
	    break;
	  /* Reconstruct x = t ? y : z;
	     as (void) t ? x = y : x = z;  */
	  tree var = TREE_OPERAND (n->init, 0);
	  tree var_type = TREE_TYPE (var);
	  tree cond = COND_EXPR_COND (old_expr);
	  /* We are allowed a void type throw in one or both of the cond
	     expr arms.  */
	  tree then_cl = COND_EXPR_THEN (old_expr);
	  if (!VOID_TYPE_P (TREE_TYPE (then_cl)))
	    {
	      gcc_checking_assert (TREE_CODE (then_cl) != STATEMENT_LIST);
	      then_cl
		= build2 (init_expr ? INIT_EXPR : MODIFY_EXPR, var_type,
			  var, then_cl);
	    }
	  tree else_cl = COND_EXPR_ELSE (old_expr);
	  if (!VOID_TYPE_P (TREE_TYPE (else_cl)))
	    {
	      gcc_checking_assert (TREE_CODE (else_cl) != STATEMENT_LIST);
	      else_cl
		= build2 (init_expr ? INIT_EXPR : MODIFY_EXPR, var_type,
			  var, else_cl);
	    }
	  n->init = build3 (COND_EXPR, var_type, cond, then_cl, else_cl);
	}
	/* FALLTHROUGH */
      case COND_EXPR:
	{
	  tree *found;
	  tree cond = COND_EXPR_COND (n->init);
	  /* If the condition contains an await expression, then we need to
	     set that first and use a separate var.  */
	  if (cp_walk_tree (&cond, find_any_await, &found, NULL))
	    {
	      tree cond_type = TREE_TYPE (cond);
	      tree cond_var  = build_lang_decl (VAR_DECL, NULL_TREE, cond_type);
	      DECL_ARTIFICIAL (cond_var) = true;
	      layout_decl (cond_var, 0);
	      gcc_checking_assert (!TYPE_NEEDS_CONSTRUCTING (cond_type));
	      cond = build2 (INIT_EXPR, cond_type, cond_var, cond);
	      var_nest_node *ins
		= new var_nest_node (cond_var, cond, n->prev, n);
	      COND_EXPR_COND (n->init) = cond_var;
	      flatten_await_stmt (ins, promoted, temps_used, NULL);
	    }

	  n->then_cl
	    = new var_nest_node (n->var, COND_EXPR_THEN (n->init), NULL, NULL);
	  n->else_cl
	    = new var_nest_node (n->var, COND_EXPR_ELSE (n->init), NULL, NULL);
	  flatten_await_stmt (n->then_cl, promoted, temps_used, NULL);
	  /* Point to the start of the flattened code.  */
	  while (n->then_cl->prev)
	    n->then_cl = n->then_cl->prev;
	  flatten_await_stmt (n->else_cl, promoted, temps_used, NULL);
	  while (n->else_cl->prev)
	    n->else_cl = n->else_cl->prev;
	  return;
	}
	break;
    }
  coro_interesting_subtree v = { NULL, temps_used };
  tree t = cp_walk_tree (&n->init, find_interesting_subtree, (void *)&v, NULL);
  if (!t)
    return;
  switch (TREE_CODE (t))
    {
      default: break;
      case CO_AWAIT_EXPR:
	{
	  /* Await expressions with initializers have a compiler-temporary
	     as the awaitable.  'promote' this.  */
	  tree var = TREE_OPERAND (t, 1);
	  bool already_present = promoted->add (var);
	  gcc_checking_assert (!already_present);
	  tree init = TREE_OPERAND (t, 2);
	  switch (TREE_CODE (init))
	    {
	      default: break;
	      case INIT_EXPR:
	      case MODIFY_EXPR:
		{
		  tree inner = TREE_OPERAND (init, 1);
		  /* We can have non-lvalue-expressions here, but when we see
		     a target expression, mark it as already used.  */
		  if (TREE_CODE (inner) == TARGET_EXPR)
		    {
		      temps_used->add (inner);
		      gcc_checking_assert
			(TREE_CODE (TREE_OPERAND (inner, 1)) != COND_EXPR);
		    }
		}
		break;
	      case CALL_EXPR:
		/* If this is a call and not a CTOR, then we didn't expect it.  */
		gcc_checking_assert
		  (DECL_CONSTRUCTOR_P (TREE_OPERAND (CALL_EXPR_FN (init), 0)));
		break;
	    }
	  var_nest_node *ins = new var_nest_node (var, init, n->prev, n);
	  TREE_OPERAND (t, 2) = NULL_TREE;
	  flatten_await_stmt (ins, promoted, temps_used, NULL);
	  flatten_await_stmt (n, promoted, temps_used, NULL);
	  return;
	}
	break;
      case TARGET_EXPR:
	{
	  /* We have a temporary; promote it, but allow for the idiom in code
	     generated by the compiler like
	     a = (target_expr produces temp, op uses temp).  */
	  tree init = t;
	  temps_used->add (init);
	  tree var_type = TREE_TYPE (init);
	  char *buf = xasprintf ("D.%d", DECL_UID (TREE_OPERAND (init, 0)));
	  tree var = build_lang_decl (VAR_DECL, get_identifier (buf), var_type);
	  DECL_ARTIFICIAL (var) = true;
	  free (buf);
	  bool already_present = promoted->add (var);
	  gcc_checking_assert (!already_present);
	  tree inner = TREE_OPERAND (init, 1);
	  gcc_checking_assert (TREE_CODE (inner) != COND_EXPR);
	  init = cp_build_modify_expr (input_location, var, INIT_EXPR, init,
				       tf_warning_or_error);
	  /* Simplify for the case that we have an init containing the temp
	     alone.  */
	  if (t == n->init && n->var == NULL_TREE)
	    {
	      n->var = var;
	      proxy_replace pr = {TREE_OPERAND (t, 0), var};
	      cp_walk_tree (&init, replace_proxy, &pr, NULL);
	      n->init = init;
	      if (replace_in)
		cp_walk_tree (replace_in, replace_proxy, &pr, NULL);
	      flatten_await_stmt (n, promoted, temps_used, NULL);
	    }
	  else
	    {
	      var_nest_node *ins
		= new var_nest_node (var, init, n->prev, n);
	      /* We have to replace the target expr... */
	      *v.entry = var;
	      /* ... and any uses of its var.  */
	      proxy_replace pr = {TREE_OPERAND (t, 0), var};
	      cp_walk_tree (&n->init, replace_proxy, &pr, NULL);
	      /* Compiler-generated temporaries can also have uses in
		 following arms of compound expressions, which will be listed
		 in 'replace_in' if present.  */
	      if (replace_in)
		cp_walk_tree (replace_in, replace_proxy, &pr, NULL);
	      flatten_await_stmt (ins, promoted, temps_used, NULL);
	      flatten_await_stmt (n, promoted, temps_used, NULL);
	    }
	  return;
	}
	break;
    }
}

/* Helper for 'process_conditional' that handles recursion into nested
   conditionals.  */

static void
handle_nested_conditionals (var_nest_node *n, vec<tree>& list,
			    hash_map<tree, tree>& map)
{
  do
    {
      if (n->var && DECL_NAME (n->var))
	{
	  list.safe_push (n->var);
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (n->var)))
	    {
	      bool existed;
	      tree& flag = map.get_or_insert (n->var, &existed);
	      if (!existed)
		{
		  /* We didn't see this var before and it needs a DTOR, so
		     build a guard variable for it.  */
		  char *nam
		    = xasprintf ("%s_guard",
				 IDENTIFIER_POINTER (DECL_NAME (n->var)));
		  flag = build_lang_decl (VAR_DECL, get_identifier (nam),
					  boolean_type_node);
		  free (nam);
		  DECL_ARTIFICIAL (flag) = true;
		}

	      /* The initializer for this variable is replaced by a compound
		 expression that performs the init and then records that the
		 variable is live (and the DTOR should be run at the scope
		 exit.  */
	      tree set_flag = build2 (INIT_EXPR, boolean_type_node,
				      flag, boolean_true_node);
	      n->init
		= build2 (COMPOUND_EXPR, boolean_type_node, n->init, set_flag);
	}
	}
      if (TREE_CODE (n->init) == COND_EXPR)
	{
	  tree new_then = push_stmt_list ();
	  handle_nested_conditionals (n->then_cl, list, map);
	  new_then = pop_stmt_list (new_then);
	  tree new_else = push_stmt_list ();
	  handle_nested_conditionals (n->else_cl, list, map);
	  new_else = pop_stmt_list (new_else);
	  tree new_if
	    = build4 (IF_STMT, void_type_node, COND_EXPR_COND (n->init),
		      new_then, new_else, NULL_TREE);
	  add_stmt (new_if);
	}
      else
	finish_expr_stmt (n->init);
      n = n->next;
    } while (n);
}

/* helper for 'maybe_promote_temps'.

   When we have a conditional expression which might embed await expressions
   and/or promoted variables, we need to handle it appropriately.

   The linked lists for the 'then' and 'else' clauses in a conditional node
   identify the promoted variables (but these cannot be wrapped in a regular
   cleanup).

   So recurse through the lists and build up a composite list of captured vars.
   Declare these and any guard variables needed to decide if a DTOR should be
   run.  Then embed the conditional into a try-finally expression that handles
   running each DTOR conditionally on its guard variable.  */

static void
process_conditional (var_nest_node *n, tree& vlist)
{
  tree init = n->init;
  hash_map<tree, tree> var_flags;
  auto_vec<tree> var_list;
  tree new_then = push_stmt_list ();
  handle_nested_conditionals (n->then_cl, var_list, var_flags);
  new_then = pop_stmt_list (new_then);
  tree new_else = push_stmt_list ();
  handle_nested_conditionals (n->else_cl, var_list, var_flags);
  new_else = pop_stmt_list (new_else);
  /* Declare the vars.  There are two loops so that the boolean flags are
     grouped in the frame.  */
  for (unsigned i = 0; i < var_list.length(); i++)
    {
      tree var = var_list[i];
      DECL_CHAIN (var) = vlist;
      vlist = var;
      add_decl_expr (var);
    }
  /* Define the guard flags for variables that need a DTOR.  */
  for (unsigned i = 0; i < var_list.length(); i++)
    {
      tree *flag = var_flags.get (var_list[i]);
      if (flag)
	{
	  DECL_INITIAL (*flag) = boolean_false_node;
	  DECL_CHAIN (*flag) = vlist;
	  vlist = *flag;
	  add_decl_expr (*flag);
	}
    }
  tree new_if
    = build4 (IF_STMT, void_type_node, COND_EXPR_COND (init),
	      new_then, new_else, NULL_TREE);
  /* Build a set of conditional DTORs.  */
  tree final_actions = push_stmt_list ();
  while (!var_list.is_empty())
    {
      tree var = var_list.pop ();
      tree *flag = var_flags.get (var);
      if (!flag)
	continue;
      tree var_type = TREE_TYPE (var);
      tree cleanup
	= build_special_member_call (var, complete_dtor_identifier,
				     NULL, var_type, LOOKUP_NORMAL,
				     tf_warning_or_error);
      tree cond_cleanup = begin_if_stmt ();
      finish_if_stmt_cond (*flag, cond_cleanup);
      finish_expr_stmt (cleanup);
      finish_then_clause (cond_cleanup);
      finish_if_stmt (cond_cleanup);
    }
  final_actions = pop_stmt_list (final_actions);
  tree try_finally
    = build2 (TRY_FINALLY_EXPR, void_type_node, new_if, final_actions);
  add_stmt (try_finally);
}

/* Given *STMT, that contains at least one await expression.

   The full expression represented in the original source code will contain
   suspension points, but it is still required that the lifetime of temporary
   values extends to the end of the expression.

   We already have a mechanism to 'promote' user-authored local variables
   to a coroutine frame counterpart (which allows explicit management of the
   lifetime across suspensions).  The transform here re-writes STMT into
   a bind expression, promotes temporary values into local variables in that
   and flattens the statement into a series of cleanups.

   Conditional expressions are re-written to regular 'if' statements.
   The cleanups for variables initialized inside a conditional (including
   nested cases) are wrapped in a try-finally clause, with guard variables
   to determine which DTORs need to be run.  */

static tree
maybe_promote_temps (tree *stmt, void *d)
{
  susp_frame_data *awpts = (susp_frame_data *) d;

  location_t sloc = EXPR_LOCATION (*stmt);
  tree expr = *stmt;
  /* Strip off uninteresting wrappers.  */
  if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
    expr = TREE_OPERAND (expr, 0);
  if (TREE_CODE (expr) == EXPR_STMT)
    expr = EXPR_STMT_EXPR (expr);
  if (TREE_CODE (expr) == CONVERT_EXPR
      && VOID_TYPE_P (TREE_TYPE (expr)))
    expr = TREE_OPERAND (expr, 0);
  STRIP_NOPS (expr);

  /* We walk the statement trees, flattening it into an ordered list of
     variables with initializers and fragments corresponding to compound
     expressions, truth or/and if and ternary conditionals.  Conditional
     expressions carry a nested list of fragments for the then and else
     clauses.  We anchor to the 'bottom' of the fragment list; we will write
     a cleanup nest with one shell for each variable initialized.  */
  var_nest_node *root = new var_nest_node (NULL_TREE, expr, NULL, NULL);
  /* Check to see we didn't promote one twice.  */
  hash_set<tree> promoted_vars;
  hash_set<tree> used_temps;
  flatten_await_stmt (root, &promoted_vars, &used_temps, NULL);

  gcc_checking_assert (root->next == NULL);
  tree vlist = NULL_TREE;
  var_nest_node *t = root;
  /* We build the bind scope expression from the bottom-up.
     EXPR_LIST holds the inner expression nest at the current cleanup
     level (becoming the final expression list when we've exhausted the
     number of sub-expression fragments).  */
  tree expr_list = NULL_TREE;
  do
    {
      tree new_list = push_stmt_list ();
      /* When we have a promoted variable, then add that to the bind scope
	 and initialize it.  When there's no promoted variable, we just need
	 to run the initializer.
	 If the initializer is a conditional expression, we need to collect
	 and declare any promoted variables nested within it.  DTORs for such
	 variables must be run conditionally too.  */
      if (t->var && DECL_NAME (t->var))
	{
	  tree var = t->var;
	  DECL_CHAIN (var) = vlist;
	  vlist = var;
	  add_decl_expr (var);
	  if (TREE_CODE (t->init) == COND_EXPR)
	    process_conditional (t, vlist);
	  else
	    finish_expr_stmt (t->init);
	  tree var_type = TREE_TYPE (var);
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (var_type))
	    {
	      tree cleanup
		= build_special_member_call (var, complete_dtor_identifier,
					     NULL, var_type, LOOKUP_NORMAL,
					     tf_warning_or_error);
	      tree cl = build_stmt (sloc, CLEANUP_STMT, expr_list, cleanup, var);
	      add_stmt (cl); /* push this onto the level above.  */
	    }
	  else if (expr_list)
	    {
	      if (TREE_CODE (expr_list) != STATEMENT_LIST)
		add_stmt (expr_list);
	      else if (!tsi_end_p (tsi_start (expr_list)))
		add_stmt (expr_list);
	    }
	}
      else
	{
	  if (TREE_CODE (t->init) == COND_EXPR)
	    process_conditional (t, vlist);
	  else
	    finish_expr_stmt (t->init);
	  if (expr_list)
	    {
	      if (TREE_CODE (expr_list) != STATEMENT_LIST)
		add_stmt (expr_list);
	      else if (!tsi_end_p (tsi_start (expr_list)))
		add_stmt (expr_list);
	    }
	}
      expr_list = pop_stmt_list (new_list);
      var_nest_node *old = t;
      t = t->prev;
      delete old;
    } while (t);

  /* Now produce the bind expression containing the 'promoted' temporaries
     as its variable list, and the cleanup nest as the statement.  */
  tree await_bind = build3_loc (sloc, BIND_EXPR, void_type_node,
				NULL, NULL, NULL);
  BIND_EXPR_BODY (await_bind) = expr_list;
  BIND_EXPR_VARS (await_bind) = nreverse (vlist);
  tree b_block = make_node (BLOCK);
  if (!awpts->block_stack->is_empty ())
    {
      tree s_block = awpts->block_stack->last ();
      if (s_block)
	{
	BLOCK_SUPERCONTEXT (b_block) = s_block;
	BLOCK_CHAIN (b_block) = BLOCK_SUBBLOCKS (s_block);
	BLOCK_SUBBLOCKS (s_block) = b_block;
	}
    }
  BLOCK_VARS (b_block) = BIND_EXPR_VARS (await_bind) ;
  BIND_EXPR_BLOCK (await_bind) = b_block;
  TREE_SIDE_EFFECTS (await_bind) = TREE_SIDE_EFFECTS (BIND_EXPR_BODY (await_bind));
  *stmt = await_bind;
  hash_set<tree> visited;
  return cp_walk_tree (stmt, register_awaits, d, &visited);
}

/* Lightweight callback to determine two key factors:
   1) If the statement/expression contains any await expressions.
   2) If the statement/expression potentially requires a re-write to handle
      TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion
      so that the await expressions are not processed in the case of the
      short-circuit arm.

   CO_YIELD expressions are re-written to their underlying co_await.  */

static tree
analyze_expression_awaits (tree *stmt, int *do_subtree, void *d)
{
  susp_frame_data *awpts = (susp_frame_data *) d;

  switch (TREE_CODE (*stmt))
    {
      default: return NULL_TREE;
      case CO_YIELD_EXPR:
	/* co_yield is syntactic sugar, re-write it to co_await.  */
	*stmt = TREE_OPERAND (*stmt, 1);
	/* FALLTHROUGH */
      case CO_AWAIT_EXPR:
	awpts->saw_awaits++;
	/* A non-null initializer for the awaiter means we need to expand.  */
	if (TREE_OPERAND (*stmt, 2))
	  awpts->has_awaiter_init = true;
	break;
      case TRUTH_ANDIF_EXPR:
      case TRUTH_ORIF_EXPR:
	{
	  /* We don't need special action for awaits in the always-executed
	     arm of a TRUTH_IF.  */
	  if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 0),
				       analyze_expression_awaits, d, NULL))
	    return res;
	  /* However, if there are await expressions on the conditionally
	     executed branch, we must expand the TRUTH_IF to ensure that the
	     expanded await expression control-flow is fully contained in the
	     conditionally executed code.  */
	  unsigned aw_count = awpts->saw_awaits;
	  if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 1),
				       analyze_expression_awaits, d, NULL))
	    return res;
	  if (awpts->saw_awaits > aw_count)
	    {
	      awpts->truth_aoif_to_expand->add (*stmt);
	      awpts->needs_truth_if_exp = true;
	    }
	  /* We've done the sub-trees here.  */
	  *do_subtree = 0;
	}
	break;
    }

  return NULL_TREE; /* Recurse until done.  */
}

/* Given *EXPR
   If EXPR contains a TRUTH_{AND,OR}IF_EXPR, TAOIE with an await expr on
   the conditionally executed branch, change this in a ternary operator.

   bool not_expr = TAOIE == TRUTH_ORIF_EXPR ? NOT : NOP;
   not_expr (always-exec expr) ? conditionally-exec expr : not_expr;

   Apply this recursively to the condition and the conditionally-exec
   branch.  */

struct truth_if_transform {
  tree *orig_stmt;
  tree scratch_var;
  hash_set<tree> *truth_aoif_to_expand;
};

static tree
expand_one_truth_if (tree *expr, int *do_subtree, void *d)
{
  truth_if_transform *xform = (truth_if_transform *) d;

  bool needs_not = false;
  switch (TREE_CODE (*expr))
    {
      default: break;
      case TRUTH_ORIF_EXPR:
	needs_not = true;
	/* FALLTHROUGH */
      case TRUTH_ANDIF_EXPR:
	{
	  if (!xform->truth_aoif_to_expand->contains (*expr))
	    break;

	  location_t sloc = EXPR_LOCATION (*expr);
	  /* Transform truth expression into a cond expression with
	     * the always-executed arm as the condition.
	     * the conditionally-executed arm as the then clause.
	     * the 'else' clause is fixed: 'true' for ||,'false' for &&.  */
	  tree cond = TREE_OPERAND (*expr, 0);
	  tree test1 = TREE_OPERAND (*expr, 1);
	  tree fixed = needs_not ? boolean_true_node : boolean_false_node;
	  if (needs_not)
	    cond = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
	  tree cond_expr
	    = build3_loc (sloc, COND_EXPR, boolean_type_node,
			  cond, test1, fixed);
	  *expr = cond_expr;
	  if (tree res = cp_walk_tree (&COND_EXPR_COND (*expr),
				       expand_one_truth_if, d, NULL))
	    return res;
	  if (tree res = cp_walk_tree (&COND_EXPR_THEN (*expr),
				       expand_one_truth_if, d, NULL))
	    return res;
	  /* We've manually processed necessary sub-trees here.  */
	  *do_subtree = 0;
	}
	break;
    }
  return NULL_TREE;
}

/* Helper that adds a new variable of VAR_TYPE to a bind scope BIND, the
   name is made up from NAM_ROOT, NAM_VERS.  */

static tree
add_var_to_bind (tree& bind, tree var_type,
		 const char *nam_root, unsigned nam_vers)
{
  tree b_vars = BIND_EXPR_VARS (bind);
  /* Build a variable to hold the condition, this will be included in the
     frame as a local var.  */
  char *nam = xasprintf ("%s.%d", nam_root, nam_vers);
  tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
  free (nam);
  DECL_CHAIN (newvar) = b_vars;
  BIND_EXPR_VARS (bind) = newvar;
  return newvar;
}

/* Helper to build and add if (!cond) break;  */

static void
coro_build_add_if_not_cond_break (tree cond)
{
  tree if_stmt = begin_if_stmt ();
  tree invert = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
  finish_if_stmt_cond (invert, if_stmt);
  finish_break_stmt ();
  finish_then_clause (if_stmt);
  finish_if_stmt (if_stmt);
}

/* Tree walk callback to replace continue statements with goto label.  */
static tree
replace_continue (tree *stmt, int *do_subtree, void *d)
{
  tree expr = *stmt;
  if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
    expr = TREE_OPERAND (expr, 0);
  if (CONVERT_EXPR_P (expr) && VOID_TYPE_P (expr))
    expr = TREE_OPERAND (expr, 0);
  STRIP_NOPS (expr);
  if (!STATEMENT_CLASS_P (expr))
    return NULL_TREE;

  switch (TREE_CODE (expr))
    {
      /* Unless it's a special case, just walk the subtrees as usual.  */
      default: return NULL_TREE;

      case CONTINUE_STMT:
	{
	  tree *label = (tree *)d;
	  location_t loc = EXPR_LOCATION (expr);
	  /* re-write a continue to goto label.  */
	  *stmt = build_stmt (loc, GOTO_EXPR, *label);
	  *do_subtree = 0;
	  return NULL_TREE;
	}

      /* Statements that do not require recursion.  */
      case DECL_EXPR:
      case BREAK_STMT:
      case GOTO_EXPR:
      case LABEL_EXPR:
      case CASE_LABEL_EXPR:
      case ASM_EXPR:
      /* These must break recursion.  */
      case FOR_STMT:
      case WHILE_STMT:
      case DO_STMT:
	*do_subtree = 0;
	return NULL_TREE;
    }
}

/* Tree walk callback to analyze, register and pre-process statements that
   contain await expressions.  */

static tree
await_statement_walker (tree *stmt, int *do_subtree, void *d)
{
  tree res = NULL_TREE;
  susp_frame_data *awpts = (susp_frame_data *) d;

  /* Process a statement at a time.  */
  if (TREE_CODE (*stmt) == BIND_EXPR)
    {
      /* For conditional expressions, we might wish to add an artificial var
	 to their containing bind expr.  */
      vec_safe_push (awpts->bind_stack, *stmt);
      /* We might need to insert a new bind expression, and want to link it
	 into the correct scope, so keep a note of the current block scope.  */
      tree blk = BIND_EXPR_BLOCK (*stmt);
      vec_safe_push (awpts->block_stack, blk);
      res = cp_walk_tree (&BIND_EXPR_BODY (*stmt), await_statement_walker,
			  d, NULL);
      awpts->block_stack->pop ();
      awpts->bind_stack->pop ();
      *do_subtree = 0; /* Done subtrees.  */
      return res;
    }
  else if (TREE_CODE (*stmt) == STATEMENT_LIST)
    {
      for (tree &s : tsi_range (*stmt))
	{
	  res = cp_walk_tree (&s, await_statement_walker,
			      d, NULL);
	  if (res)
	    return res;
	}
      *do_subtree = 0; /* Done subtrees.  */
      return NULL_TREE;
    }

  /* We have something to be handled as a single statement.  We have to handle
     a few statements specially where await statements have to be moved out of
     constructs.  */
  tree expr = *stmt;
  if (TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
    expr = TREE_OPERAND (expr, 0);
  STRIP_NOPS (expr);

  if (STATEMENT_CLASS_P (expr))
    switch (TREE_CODE (expr))
      {
	/* Unless it's a special case, just walk the subtrees as usual.  */
	default: return NULL_TREE;

	/* When we have a conditional expression, which contains one or more
	   await expressions, we have to break the condition out into a
	   regular statement so that the control flow introduced by the await
	   transforms can be implemented.  */
	case IF_STMT:
	  {
	    tree *await_ptr;
	    hash_set<tree> visited;
	    /* Transform 'if (cond with awaits) then stmt1 else stmt2' into
	       bool cond = cond with awaits.
	       if (cond) then stmt1 else stmt2.  */
	    tree if_stmt = *stmt;
	    /* We treat the condition as if it was a stand-alone statement,
	       to see if there are any await expressions which will be analyzed
	       and registered.  */
	    if (!(cp_walk_tree (&IF_COND (if_stmt),
		  find_any_await, &await_ptr, &visited)))
	      return NULL_TREE; /* Nothing special to do here.  */

	    gcc_checking_assert (!awpts->bind_stack->is_empty());
	    tree& bind_expr = awpts->bind_stack->last ();
	    tree newvar = add_var_to_bind (bind_expr, boolean_type_node,
					   "ifcd", awpts->cond_number++);
	    tree insert_list = push_stmt_list ();
	    tree cond_inner = IF_COND (if_stmt);
	    if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
	      cond_inner = TREE_OPERAND (cond_inner, 0);
	    add_decl_expr (newvar);
	    location_t sloc = EXPR_LOCATION (IF_COND (if_stmt));
	    /* We want to initialize the new variable with the expression
	       that contains the await(s) and potentially also needs to
	       have truth_if expressions expanded.  */
	    tree new_s = build2_loc (sloc, INIT_EXPR, boolean_type_node,
				     newvar, cond_inner);
	    finish_expr_stmt (new_s);
	    IF_COND (if_stmt) = newvar;
	    add_stmt (if_stmt);
	    *stmt = pop_stmt_list (insert_list);
	    /* So now walk the new statement list.  */
	    res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
	    *do_subtree = 0; /* Done subtrees.  */
	    return res;
	  }
	  break;
	case FOR_STMT:
	  {
	    tree *await_ptr;
	    hash_set<tree> visited;
	    /* for loops only need special treatment if the condition or the
	       iteration expression contain a co_await.  */
	    tree for_stmt = *stmt;
	    /* At present, the FE always generates a separate initializer for
	       the FOR_INIT_STMT, when the expression has an await.  Check that
	       this assumption holds in the future. */
	    gcc_checking_assert
	      (!(cp_walk_tree (&FOR_INIT_STMT (for_stmt), find_any_await,
			       &await_ptr, &visited)));

	    visited.empty ();
	    bool for_cond_await
	      = cp_walk_tree (&FOR_COND (for_stmt), find_any_await,
			      &await_ptr, &visited);

	    visited.empty ();
	    bool for_expr_await
	      = cp_walk_tree (&FOR_EXPR (for_stmt), find_any_await,
			      &await_ptr, &visited);

	    /* If the condition has an await, then we will need to rewrite the
	       loop as
	       for (init expression;true;iteration expression) {
		  condition = await expression;
		  if (condition)
		    break;
		  ...
		}
	    */
	    if (for_cond_await)
	      {
		tree insert_list = push_stmt_list ();
		/* This will be expanded when the revised body is handled.  */
		coro_build_add_if_not_cond_break (FOR_COND (for_stmt));
		/* .. add the original for body.  */
		add_stmt (FOR_BODY (for_stmt));
		/* To make the new for body.  */
		FOR_BODY (for_stmt) = pop_stmt_list (insert_list);
		FOR_COND (for_stmt) = boolean_true_node;
	      }
	    /* If the iteration expression has an await, it's a bit more
	       tricky.
	       for (init expression;condition;) {
		 ...
		 iteration_expr_label:
		   iteration expression with await;
	       }
	       but, then we will need to re-write any continue statements into
	       'goto iteration_expr_label:'.
	    */
	    if (for_expr_await)
	      {
		location_t sloc = EXPR_LOCATION (FOR_EXPR (for_stmt));
		tree insert_list = push_stmt_list ();
		/* The original for body.  */
		add_stmt (FOR_BODY (for_stmt));
		char *buf = xasprintf ("for.iter.expr.%u", awpts->cond_number++);
		tree it_expr_label
		  = create_named_label_with_ctx (sloc, buf, NULL_TREE);
		free (buf);
		add_stmt (build_stmt (sloc, LABEL_EXPR, it_expr_label));
		tree for_expr = FOR_EXPR (for_stmt);
		/* Present the iteration expression as a statement.  */
		if (TREE_CODE (for_expr) == CLEANUP_POINT_EXPR)
		  for_expr = TREE_OPERAND (for_expr, 0);
		STRIP_NOPS (for_expr);
		finish_expr_stmt (for_expr);
		FOR_EXPR (for_stmt) = NULL_TREE;
		FOR_BODY (for_stmt) = pop_stmt_list (insert_list);
		/* rewrite continue statements to goto label.  */
		hash_set<tree> visited_continue;
		if ((res = cp_walk_tree (&FOR_BODY (for_stmt),
		     replace_continue, &it_expr_label, &visited_continue)))
		  return res;
	      }

	    /* So now walk the body statement (list), if there were no await
	       expressions, then this handles the original body - and either
	       way we will have finished with this statement.  */
	    res = cp_walk_tree (&FOR_BODY (for_stmt),
				await_statement_walker, d, NULL);
	    *do_subtree = 0; /* Done subtrees.  */
	    return res;
	  }
	  break;
	case WHILE_STMT:
	  {
	    /* We turn 'while (cond with awaits) stmt' into
	       while (true) {
		  if (!(cond with awaits))
		    break;
		  stmt..
		} */
	    tree *await_ptr;
	    hash_set<tree> visited;
	    tree while_stmt = *stmt;
	    if (!(cp_walk_tree (&WHILE_COND (while_stmt),
		  find_any_await, &await_ptr, &visited)))
	      return NULL_TREE; /* Nothing special to do here.  */

	    tree insert_list = push_stmt_list ();
	    coro_build_add_if_not_cond_break (WHILE_COND (while_stmt));
	    /* The original while body.  */
	    add_stmt (WHILE_BODY (while_stmt));
	    /* The new while body.  */
	    WHILE_BODY (while_stmt) = pop_stmt_list (insert_list);
	    WHILE_COND (while_stmt) = boolean_true_node;
	    /* So now walk the new statement list.  */
	    res = cp_walk_tree (&WHILE_BODY (while_stmt),
				await_statement_walker, d, NULL);
	    *do_subtree = 0; /* Done subtrees.  */
	    return res;
	  }
	  break;
	case DO_STMT:
	  {
	    /* We turn do stmt while (cond with awaits) into:
	       do {
		  stmt..
		  if (!(cond with awaits))
		    break;
	       } while (true); */
	    tree do_stmt = *stmt;
	    tree *await_ptr;
	    hash_set<tree> visited;
	    if (!(cp_walk_tree (&DO_COND (do_stmt),
		  find_any_await, &await_ptr, &visited)))
	      return NULL_TREE; /* Nothing special to do here.  */

	    tree insert_list = push_stmt_list ();
	    /* The original do stmt body.  */
	    add_stmt (DO_BODY (do_stmt));
	    coro_build_add_if_not_cond_break (DO_COND (do_stmt));
	    /* The new while body.  */
	    DO_BODY (do_stmt) = pop_stmt_list (insert_list);
	    DO_COND (do_stmt) = boolean_true_node;
	    /* So now walk the new statement list.  */
	    res = cp_walk_tree (&DO_BODY (do_stmt), await_statement_walker,
				d, NULL);
	    *do_subtree = 0; /* Done subtrees.  */
	    return res;
	  }
	  break;
	case SWITCH_STMT:
	  {
	    /* We turn 'switch (cond with awaits) stmt' into
	       switch_type cond = cond with awaits
	       switch (cond) stmt.  */
	    tree sw_stmt = *stmt;
	    tree *await_ptr;
	    hash_set<tree> visited;
	    if (!(cp_walk_tree (&SWITCH_STMT_COND (sw_stmt),
		  find_any_await, &await_ptr, &visited)))
	      return NULL_TREE; /* Nothing special to do here.  */

	    gcc_checking_assert (!awpts->bind_stack->is_empty());
	    /* Build a variable to hold the condition, this will be
		   included in the frame as a local var.  */
	    tree& bind_expr = awpts->bind_stack->last ();
	    tree sw_type = SWITCH_STMT_TYPE (sw_stmt);
	    tree newvar = add_var_to_bind (bind_expr, sw_type, "swch",
					   awpts->cond_number++);
	    tree insert_list = push_stmt_list ();
	    add_decl_expr (newvar);

	    tree cond_inner = SWITCH_STMT_COND (sw_stmt);
	    if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
	      cond_inner = TREE_OPERAND (cond_inner, 0);
	    location_t sloc = EXPR_LOCATION (SWITCH_STMT_COND (sw_stmt));
	    tree new_s = build2_loc (sloc, INIT_EXPR, sw_type, newvar,
				     cond_inner);
	    finish_expr_stmt (new_s);
	    SWITCH_STMT_COND (sw_stmt) = newvar;
	    /* Now add the switch statement with the condition re-
		   written to use the local var.  */
	    add_stmt (sw_stmt);
	    *stmt = pop_stmt_list (insert_list);
	    /* Process the expanded list.  */
	    res = cp_walk_tree (stmt, await_statement_walker,
				d, NULL);
	    *do_subtree = 0; /* Done subtrees.  */
	    return res;
	  }
	  break;
	case CO_RETURN_EXPR:
	  {
	    /* Expand the co_return as per [stmt.return.coroutine]
	       - for co_return;
		{ p.return_void (); goto final_suspend; }
	       - for co_return [void expr];
		{ expr; p.return_void(); goto final_suspend;}
	       - for co_return [non void expr];
		{ p.return_value(expr); goto final_suspend; }  */
	    location_t loc = EXPR_LOCATION (expr);
	    tree call = TREE_OPERAND (expr, 1);
	    expr = TREE_OPERAND (expr, 0);
	    tree ret_list = push_stmt_list ();
	    /* [stmt.return.coroutine], 2.2
	       If expr is present and void, it is placed immediately before
	       the call for return_void;  */
	    if (expr && VOID_TYPE_P (TREE_TYPE (expr)))
	      finish_expr_stmt (expr);
	    /* Insert p.return_{void,value(expr)}.  */
	    finish_expr_stmt (call);
	    TREE_USED (awpts->fs_label) = 1;
	    add_stmt (build_stmt (loc, GOTO_EXPR, awpts->fs_label));
	    *stmt = pop_stmt_list (ret_list);
	    res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
	    /* Once this is complete, we will have processed subtrees.  */
	    *do_subtree = 0;
	    return res;
	  }
	  break;
	case HANDLER:
	  {
	    /* [expr.await] An await-expression shall appear only in a
	       potentially-evaluated expression within the compound-statement
	       of a function-body outside of a handler.  */
	    tree *await_ptr;
	    hash_set<tree> visited;
	    if (!(cp_walk_tree (&HANDLER_BODY (expr), find_any_await,
		  &await_ptr, &visited)))
	      return NULL_TREE; /* All OK.  */
	    location_t loc = EXPR_LOCATION (*await_ptr);
	    error_at (loc, "await expressions are not permitted in handlers");
	    return NULL_TREE; /* This is going to fail later anyway.  */
	  }
	  break;
      }
  else if (EXPR_P (expr))
    {
      hash_set<tree> visited;
      tree *await_ptr;
      if (!(cp_walk_tree (stmt, find_any_await, &await_ptr, &visited)))
	return NULL_TREE; /* Nothing special to do here.  */

      visited.empty ();
      awpts->saw_awaits = 0;
      hash_set<tree> truth_aoif_to_expand;
      awpts->truth_aoif_to_expand = &truth_aoif_to_expand;
      awpts->needs_truth_if_exp = false;
      awpts->has_awaiter_init = false;
      if ((res = cp_walk_tree (stmt, analyze_expression_awaits, d, &visited)))
	return res;
      *do_subtree = 0; /* Done subtrees.  */
      if (!awpts->saw_awaits)
	return NULL_TREE; /* Nothing special to do here.  */

      if (awpts->needs_truth_if_exp)
	{
	  /* If a truth-and/or-if expression has an await expression in the
	     conditionally-taken branch, then it must be rewritten into a
	     regular conditional.  */
	  truth_if_transform xf = {stmt, NULL_TREE, &truth_aoif_to_expand};
	  if ((res = cp_walk_tree (stmt, expand_one_truth_if, &xf, NULL)))
	    return res;
	}
      /* Process this statement, which contains at least one await expression
	 to 'promote' temporary values to a coroutine frame slot.  */
      return maybe_promote_temps (stmt, d);
    }
  /* Continue recursion, if needed.  */
  return res;
}

/* For figuring out what param usage we have.  */

struct param_frame_data
{
  tree *field_list;
  hash_map<tree, param_info> *param_uses;
  hash_set<tree *> *visited;
  location_t loc;
  bool param_seen;
};

/* A tree walk callback that rewrites each parm use to the local variable
   that represents its copy in the frame.  */

static tree
rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
{
  param_frame_data *data = (param_frame_data *) d;

  /* For lambda closure content, we have to look specifically.  */
  if (TREE_CODE (*stmt) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*stmt))
    {
      tree t = DECL_VALUE_EXPR (*stmt);
      return cp_walk_tree (&t, rewrite_param_uses, d, NULL);
    }

  if (TREE_CODE (*stmt) != PARM_DECL)
    return NULL_TREE;

  /* If we already saw the containing expression, then we're done.  */
  if (data->visited->add (stmt))
    return NULL_TREE;

  bool existed;
  param_info &parm = data->param_uses->get_or_insert (*stmt, &existed);
  gcc_checking_assert (existed);

  *stmt = parm.copy_var;
  return NULL_TREE;
}

/* Build up a set of info that determines how each param copy will be
   handled.  */

static hash_map<tree, param_info> *
analyze_fn_parms (tree orig)
{
  if (!DECL_ARGUMENTS (orig))
    return NULL;

  hash_map<tree, param_info> *param_uses = new hash_map<tree, param_info>;

  /* Build a hash map with an entry for each param.
     The key is the param tree.
     Then we have an entry for the frame field name.
     Then a cache for the field ref when we come to use it.
     Then a tree list of the uses.
     The second two entries start out empty - and only get populated
     when we see uses.  */
  bool lambda_p = LAMBDA_FUNCTION_P (orig);

  unsigned no_name_parm = 0;
  for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
    {
      bool existed;
      param_info &parm = param_uses->get_or_insert (arg, &existed);
      gcc_checking_assert (!existed);
      parm.body_uses = NULL;
      tree actual_type = TREE_TYPE (arg);
      actual_type = complete_type_or_else (actual_type, orig);
      if (actual_type == NULL_TREE)
	actual_type = error_mark_node;
      parm.orig_type = actual_type;
      parm.by_ref = parm.pt_ref = parm.rv_ref =  false;
      if (TREE_CODE (actual_type) == REFERENCE_TYPE)
	{
	  /* If the user passes by reference, then we will save the
	     pointer to the original.  As noted in
	     [dcl.fct.def.coroutine] / 13, if the lifetime of the
	     referenced item ends and then the coroutine is resumed,
	     we have UB; well, the user asked for it.  */
	  if (TYPE_REF_IS_RVALUE (actual_type))
		parm.rv_ref = true;
	  else
		parm.pt_ref = true;
	}
      else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
	parm.by_ref = true;

      parm.frame_type = actual_type;

      parm.this_ptr = is_this_parameter (arg);
      parm.lambda_cobj = lambda_p && DECL_NAME (arg) == closure_identifier;

      tree name = DECL_NAME (arg);
      if (!name)
	{
	  char *buf = xasprintf ("_Coro_unnamed_parm_%d", no_name_parm++);
	  name = get_identifier (buf);
	  free (buf);
	}
      parm.field_id = name;

      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (parm.frame_type))
	{
	  char *buf = xasprintf ("%s%s_live", DECL_NAME (arg) ? "_Coro_" : "",
				 IDENTIFIER_POINTER (name));
	  parm.guard_var
	    = coro_build_artificial_var (UNKNOWN_LOCATION, get_identifier (buf),
					 boolean_type_node, orig,
					 boolean_false_node);
	  free (buf);
	  parm.trivial_dtor = false;
	}
      else
	parm.trivial_dtor = true;
    }

  return param_uses;
}

/* Small helper for the repetitive task of adding a new field to the coro
   frame type.  */

static tree
coro_make_frame_entry (tree *field_list, const char *name, tree fld_type,
		       location_t loc)
{
  tree id = get_identifier (name);
  tree decl = build_decl (loc, FIELD_DECL, id, fld_type);
  DECL_CHAIN (decl) = *field_list;
  *field_list = decl;
  return id;
}

/* For recording local variable usage.  */

struct local_vars_frame_data
{
  tree *field_list;
  hash_map<tree, local_var_info> *local_var_uses;
  unsigned int nest_depth, bind_indx;
  location_t loc;
  bool saw_capture;
  bool local_var_seen;
};

/* A tree-walk callback that processes one bind expression noting local
   variables, and making a coroutine frame slot available for those that
   need it, so that they can be 'promoted' across suspension points.  */

static tree
register_local_var_uses (tree *stmt, int *do_subtree, void *d)
{
  local_vars_frame_data *lvd = (local_vars_frame_data *) d;

  /* As we enter a bind expression - record the vars there and then recurse.
     As we exit drop the nest depth.
     The bind index is a growing count of how many bind indices we've seen.
     We build a space in the frame for each local var.  */

  if (TREE_CODE (*stmt) == BIND_EXPR)
    {
      tree lvar;
      for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
	   lvar = DECL_CHAIN (lvar))
	{
	  bool existed;
	  local_var_info &local_var
	    = lvd->local_var_uses->get_or_insert (lvar, &existed);
	  gcc_checking_assert (!existed);
	  local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
	  tree lvtype = TREE_TYPE (lvar);
	  local_var.frame_type = lvtype;
	  local_var.field_idx = local_var.field_id = NULL_TREE;

	  /* Make sure that we only present vars to the tests below.  */
	  if (TREE_CODE (lvar) == TYPE_DECL
	      || TREE_CODE (lvar) == NAMESPACE_DECL)
	    continue;

	  /* We don't move static vars into the frame. */
	  local_var.is_static = TREE_STATIC (lvar);
	  if (local_var.is_static)
	    continue;

	  poly_uint64 size;
	  if (TREE_CODE (lvtype) == ARRAY_TYPE
	      && !poly_int_tree_p (DECL_SIZE_UNIT (lvar), &size))
	    {
	      sorry_at (local_var.def_loc, "variable length arrays are not"
			" yet supported in coroutines");
	      /* Ignore it, this is broken anyway.  */
	      continue;
	    }

	  lvd->local_var_seen = true;
	  /* If this var is a lambda capture proxy, we want to leave it alone,
	     and later rewrite the DECL_VALUE_EXPR to indirect through the
	     frame copy of the pointer to the lambda closure object.  */
	  local_var.is_lambda_capture = is_capture_proxy (lvar);
	  if (local_var.is_lambda_capture)
	    continue;

	  /* If a variable has a value expression, then that's what needs
	     to be processed.  */
	  local_var.has_value_expr_p = DECL_HAS_VALUE_EXPR_P (lvar);
	  if (local_var.has_value_expr_p)
	    continue;

	  /* Make names depth+index unique, so that we can support nested
	     scopes with identically named locals and still be able to
	     identify them in the coroutine frame.  */
	  tree lvname = DECL_NAME (lvar);
	  char *buf;

	  /* The outermost bind scope contains the artificial variables that
	     we inject to implement the coro state machine.  We want to be able
	     to inspect these in debugging.  */
	  if (lvname != NULL_TREE && lvd->nest_depth == 0)
	    buf = xasprintf ("%s", IDENTIFIER_POINTER (lvname));
	  else if (lvname != NULL_TREE)
	    buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname),
			     lvd->nest_depth, lvd->bind_indx);
	  else
	    buf = xasprintf ("_D%u_%u_%u", DECL_UID (lvar), lvd->nest_depth,
			     lvd->bind_indx);
	  /* TODO: Figure out if we should build a local type that has any
	     excess alignment or size from the original decl.  */
	  local_var.field_id
	    = coro_make_frame_entry (lvd->field_list, buf, lvtype, lvd->loc);
	  free (buf);
	  /* We don't walk any of the local var sub-trees, they won't contain
	     any bind exprs.  */
	}
      lvd->bind_indx++;
      lvd->nest_depth++;
      cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
      *do_subtree = 0; /* We've done this.  */
      lvd->nest_depth--;
    }
  return NULL_TREE;
}

/* Build, return FUNCTION_DECL node based on ORIG with a type FN_TYPE which has
   a single argument of type CORO_FRAME_PTR.  Build the actor function if
   ACTOR_P is true, otherwise the destroy. */

static tree
coro_build_actor_or_destroy_function (tree orig, tree fn_type,
				      tree coro_frame_ptr, bool actor_p)
{
  location_t loc = DECL_SOURCE_LOCATION (orig);
  tree fn
    = build_lang_decl (FUNCTION_DECL, copy_node (DECL_NAME (orig)), fn_type);

  /* Allow for locating the ramp (original) function from this one.  */
  if (!to_ramp)
    to_ramp = hash_map<tree, tree>::create_ggc (10);
  to_ramp->put (fn, orig);

  DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
  DECL_SOURCE_LOCATION (fn) = loc;
  DECL_ARTIFICIAL (fn) = true;
  DECL_INITIAL (fn) = error_mark_node;

  tree id = get_identifier ("frame_ptr");
  tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
  DECL_CONTEXT (fp) = fn;
  DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
  DECL_ARGUMENTS (fn) = fp;

  /* Copy selected attributes from the original function.  */
  TREE_USED (fn) = TREE_USED (orig);
  if (DECL_SECTION_NAME (orig))
    set_decl_section_name (fn, orig);
  /* Copy any alignment that the FE added.  */
  if (DECL_ALIGN (orig))
    SET_DECL_ALIGN (fn, DECL_ALIGN (orig));
  /* Copy any alignment the user added.  */
  DECL_USER_ALIGN (fn) = DECL_USER_ALIGN (orig);
  /* Apply attributes from the original fn.  */
  DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig));

  /* A void return.  */
  tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
  DECL_CONTEXT (resdecl) = fn;
  DECL_ARTIFICIAL (resdecl) = 1;
  DECL_IGNORED_P (resdecl) = 1;
  DECL_RESULT (fn) = resdecl;

  /* This is a coroutine component.  */
  DECL_COROUTINE_P (fn) = 1;

  /* Set up a means to find out if a decl is one of the helpers and, if so,
     which one.  */
  if (coroutine_info *info = get_coroutine_info (orig))
    {
      gcc_checking_assert ((actor_p && info->actor_decl == NULL_TREE)
			   || info->destroy_decl == NULL_TREE);
      if (actor_p)
	info->actor_decl = fn;
      else
	info->destroy_decl = fn;
    }
  return fn;
}

/* Re-write the body as per [dcl.fct.def.coroutine] / 5.  */

static tree
coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig,
			    hash_map<tree, param_info> *param_uses,
			    tree resume_fn_ptr_type,
			    tree& resume_idx_var, tree& fs_label)
{
  /* This will be our new outer scope.  */
  tree update_body = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
  tree top_block = make_node (BLOCK);
  BIND_EXPR_BLOCK (update_body) = top_block;
  BIND_EXPR_BODY (update_body) = push_stmt_list ();

  /* If the function has a top level bind expression, then connect that
     after first making sure we give it a new block.  */
  tree first = expr_first (fnbody);
  if (first && TREE_CODE (first) == BIND_EXPR)
    {
      tree block = BIND_EXPR_BLOCK (first);
      gcc_checking_assert (block);
      gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
      gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE);
      /* Replace the top block to avoid issues with locations for args
	 appearing to be in a non-existent place.  */
      tree replace_blk = make_node (BLOCK);
      BLOCK_VARS (replace_blk) = BLOCK_VARS (block);
      BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block);
      for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b))
	BLOCK_SUPERCONTEXT (b) = replace_blk;
      BIND_EXPR_BLOCK (first) = replace_blk;
      /* The top block has one child, so far, and we have now got a 
	 superblock.  */
      BLOCK_SUPERCONTEXT (replace_blk) = top_block;
      BLOCK_SUBBLOCKS (top_block) = replace_blk;
    }

  /* Wrap the function body in a try {} catch (...) {} block, if exceptions
     are enabled.  */
  tree var_list = NULL_TREE;
  tree initial_await = build_init_or_final_await (fn_start, false);

  /* [stmt.return.coroutine] / 3
     If p.return_void() is a valid expression, flowing off the end of a
     coroutine is equivalent to a co_return with no operand; otherwise
     flowing off the end of a coroutine results in undefined behavior.  */
  tree return_void
    = get_coroutine_return_void_expr (current_function_decl, fn_start, false);

  /* The pointer to the resume function.  */
  tree resume_fn_ptr
    = coro_build_artificial_var (fn_start, coro_resume_fn_id,
				 resume_fn_ptr_type, orig, NULL_TREE);
  DECL_CHAIN (resume_fn_ptr) = var_list;
  var_list = resume_fn_ptr;
  add_decl_expr (resume_fn_ptr);

  /* We will need to be able to set the resume function pointer to nullptr
     to signal that the coroutine is 'done'.  */
  tree zero_resume
    = build1 (CONVERT_EXPR, resume_fn_ptr_type, integer_zero_node);

  /* The pointer to the destroy function.  */
  tree var = coro_build_artificial_var (fn_start, coro_destroy_fn_id,
					resume_fn_ptr_type, orig, NULL_TREE);
  DECL_CHAIN (var) = var_list;
  var_list = var;
  add_decl_expr (var);

  /* The promise was created on demand when parsing we now link it into
      our scope.  */
  tree promise = get_coroutine_promise_proxy (orig);
  DECL_CONTEXT (promise) = orig;
  DECL_SOURCE_LOCATION (promise) = fn_start;
  DECL_CHAIN (promise) = var_list;
  var_list = promise;
  add_decl_expr (promise);

  /* We need a handle to this coroutine, which is passed to every
     await_suspend().  This was created on demand when parsing we now link it
     into our scope.  */
  var = get_coroutine_self_handle_proxy (orig);
  DECL_CONTEXT (var) = orig;
  DECL_SOURCE_LOCATION (var) = fn_start;
  DECL_CHAIN (var) = var_list;
  var_list = var;
  add_decl_expr (var);

  /* If we have function parms, then these will be copied to the coroutine
     frame.  Create a local (proxy) variable for each parm, since the original
     parms will be out of scope once the ramp has finished. The proxy vars will
     get DECL_VALUE_EXPRs pointing to the frame copies, so that we can interact
     with them in the debugger.  */
  if (param_uses)
    {
      gcc_checking_assert (DECL_ARGUMENTS (orig));
      /* Add a local var for each parm.  */
      for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
	   arg = DECL_CHAIN (arg))
	{
	  param_info *parm_i = param_uses->get (arg);
	  gcc_checking_assert (parm_i);
	  parm_i->copy_var
	    = build_lang_decl (VAR_DECL, parm_i->field_id, TREE_TYPE (arg));
	  DECL_SOURCE_LOCATION (parm_i->copy_var) = DECL_SOURCE_LOCATION (arg);
	  DECL_CONTEXT (parm_i->copy_var) = orig;
	  DECL_ARTIFICIAL (parm_i->copy_var) = true;
	  DECL_CHAIN (parm_i->copy_var) = var_list;
	  var_list = parm_i->copy_var;
	  add_decl_expr (parm_i->copy_var);
      	}

      /* Now replace all uses of the parms in the function body with the proxy
	 vars.  We want to this to apply to every instance of param's use, so
	 don't include a 'visited' hash_set on the tree walk, however we will
	 arrange to visit each containing expression only once.  */
      hash_set<tree *> visited;
      param_frame_data param_data = {NULL, param_uses,
				     &visited, fn_start, false};
      cp_walk_tree (&fnbody, rewrite_param_uses, &param_data, NULL);
    }

  /* We create a resume index, this is initialized in the ramp.  */
  resume_idx_var
    = coro_build_artificial_var (fn_start, coro_resume_index_id,
				 short_unsigned_type_node, orig, NULL_TREE);
  DECL_CHAIN (resume_idx_var) = var_list;
  var_list = resume_idx_var;
  add_decl_expr (resume_idx_var);

  /* If the coroutine has a frame that needs to be freed, this will be set by
     the ramp.  */
  var = coro_build_artificial_var (fn_start, coro_frame_needs_free_id,
				   boolean_type_node, orig, NULL_TREE);
  DECL_CHAIN (var) = var_list;
  var_list = var;
  add_decl_expr (var);

  if (flag_exceptions)
    {
      /* Build promise.unhandled_exception();  */
      tree ueh
	= coro_build_promise_expression (current_function_decl, promise,
					 coro_unhandled_exception_identifier,
					 fn_start, NULL, /*musthave=*/true);
      /* Create and initialize the initial-await-resume-called variable per
	 [dcl.fct.def.coroutine] / 5.3.  */
      tree i_a_r_c
	= coro_build_artificial_var (fn_start, coro_frame_i_a_r_c_id,
				     boolean_type_node, orig,
				     boolean_false_node);
      DECL_CHAIN (i_a_r_c) = var_list;
      var_list = i_a_r_c;
      add_decl_expr (i_a_r_c);
      /* Start the try-catch.  */
      tree tcb = build_stmt (fn_start, TRY_BLOCK, NULL_TREE, NULL_TREE);
      add_stmt (tcb);
      TRY_STMTS (tcb) = push_stmt_list ();
      if (initial_await != error_mark_node)
	{
	  /* Build a compound expression that sets the
	     initial-await-resume-called variable true and then calls the
	     initial suspend expression await resume.
	     In the case that the user decides to make the initial await
	     await_resume() return a value, we need to discard it and, it is
	     a reference type, look past the indirection.  */
	  if (INDIRECT_REF_P (initial_await))
	    initial_await = TREE_OPERAND (initial_await, 0);
	  tree vec = TREE_OPERAND (initial_await, 3);
	  tree aw_r = TREE_VEC_ELT (vec, 2);
	  aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error);
	  tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c,
				boolean_true_node);
	  aw_r = cp_build_compound_expr (update, aw_r, tf_warning_or_error);
	  TREE_VEC_ELT (vec, 2) = aw_r;
	}
      /* Add the initial await to the start of the user-authored function.  */
      finish_expr_stmt (initial_await);
      /* Append the original function body.  */
      add_stmt (fnbody);
      if (return_void)
	add_stmt (return_void);
      TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb));
      TRY_HANDLERS (tcb) = push_stmt_list ();
      /* Mimic what the parser does for the catch.  */
      tree handler = begin_handler ();
      finish_handler_parms (NULL_TREE, handler); /* catch (...) */

      /* Get the initial await resume called value.  */
      tree not_iarc_if = begin_if_stmt ();
      tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR,
				  boolean_type_node, i_a_r_c);
      finish_if_stmt_cond (not_iarc, not_iarc_if);
      /* If the initial await resume called value is false, rethrow...  */
      tree rethrow = build_throw (fn_start, NULL_TREE);
      suppress_warning (rethrow);
      finish_expr_stmt (rethrow);
      finish_then_clause (not_iarc_if);
      tree iarc_scope = IF_SCOPE (not_iarc_if);
      IF_SCOPE (not_iarc_if) = NULL;
      not_iarc_if = do_poplevel (iarc_scope);
      add_stmt (not_iarc_if);
      /* ... else call the promise unhandled exception method
	 but first we set done = true and the resume index to 0.
	 If the unhandled exception method returns, then we continue
	 to the final await expression (which duplicates the clearing of
	 the field). */
      tree r = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr,
		       zero_resume);
      finish_expr_stmt (r);
      tree short_zero = build_int_cst (short_unsigned_type_node, 0);
      r = build2 (MODIFY_EXPR, short_unsigned_type_node, resume_idx_var,
		  short_zero);
      finish_expr_stmt (r);
      finish_expr_stmt (ueh);
      finish_handler (handler);
      TRY_HANDLERS (tcb) = pop_stmt_list (TRY_HANDLERS (tcb));
    }
  else
    {
      if (pedantic)
	{
	  /* We still try to look for the promise method and warn if it's not
	     present.  */
	  tree ueh_meth
	    = lookup_promise_method (orig, coro_unhandled_exception_identifier,
				     fn_start, /*musthave=*/false);
	  if (!ueh_meth || ueh_meth == error_mark_node)
	    warning_at (fn_start, 0, "no member named %qE in %qT",
			coro_unhandled_exception_identifier,
			get_coroutine_promise_type (orig));
	}
      /* Else we don't check and don't care if the method is missing..
	 just add the initial suspend, function and return.  */
      finish_expr_stmt (initial_await);
      /* Append the original function body.  */
      add_stmt (fnbody);
      if (return_void)
	add_stmt (return_void);
    }

  /* co_return branches to the final_suspend label, so declare that now.  */
  fs_label
    = create_named_label_with_ctx (fn_start, "final.suspend", NULL_TREE);
  add_stmt (build_stmt (fn_start, LABEL_EXPR, fs_label));

  /* Before entering the final suspend point, we signal that this point has
     been reached by setting the resume function pointer to zero (this is
     what the 'done()' builtin tests) as per the current ABI.  */
  zero_resume = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr,
			zero_resume);
  finish_expr_stmt (zero_resume);
  finish_expr_stmt (build_init_or_final_await (fn_start, true));
  BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body));
  BIND_EXPR_VARS (update_body) = nreverse (var_list);
  BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body);

  return update_body;
}

/* Here we:
   a) Check that the function and promise type are valid for a
      coroutine.
   b) Carry out the initial morph to create the skeleton of the
      coroutine ramp function and the rewritten body.

  Assumptions.

  1. We only hit this code once all dependencies are resolved.
  2. The function body will be either a bind expr or a statement list
  3. That cfun and current_function_decl are valid for the case we're
     expanding.
  4. 'input_location' will be of the final brace for the function.

 We do something like this:
 declare a dummy coro frame.
 struct _R_frame {
  using handle_type = coro::coroutine_handle<coro1::promise_type>;
  void (*_Coro_resume_fn)(_R_frame *);
  void (*_Coro_destroy_fn)(_R_frame *);
  coro1::promise_type _Coro_promise;
  bool _Coro_frame_needs_free; free the coro frame mem if set.
  bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3
  short _Coro_resume_index;
  handle_type _Coro_self_handle;
  parameter copies (were required).
  local variables saved (including awaitables)
  (maybe) trailing space.
 };  */

bool
morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
{
  gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL);

  *resumer = error_mark_node;
  *destroyer = error_mark_node;
  if (!coro_function_valid_p (orig))
    {
      /* For early errors, we do not want a diagnostic about the missing
	 ramp return value, since the user cannot fix this - a 'return' is
	 not allowed in a coroutine.  */
      suppress_warning (orig, OPT_Wreturn_type);
      /* Discard the body, we can't process it further.  */
      pop_stmt_list (DECL_SAVED_TREE (orig));
      DECL_SAVED_TREE (orig) = push_stmt_list ();
      return false;
    }

  /* We can't validly get here with an empty statement list, since there's no
     way for the FE to decide it's a coroutine in the absence of any code.  */
  tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
  gcc_checking_assert (fnbody != NULL_TREE);

  /* We don't have the locus of the opening brace - it's filled in later (and
     there doesn't really seem to be any easy way to get at it).
     The closing brace is assumed to be input_location.  */
  location_t fn_start = DECL_SOURCE_LOCATION (orig);
  gcc_rich_location fn_start_loc (fn_start);

  /* Initial processing of the function-body.
     If we have no expressions or just an error then punt.  */
  tree body_start = expr_first (fnbody);
  if (body_start == NULL_TREE || body_start == error_mark_node)
    {
      DECL_SAVED_TREE (orig) = push_stmt_list ();
      append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig));
      /* Suppress warnings about the missing return value.  */
      suppress_warning (orig, OPT_Wreturn_type);
      return false;
    }

  /* So, we've tied off the original user-authored body in fn_body.

     Start the replacement synthesized ramp body as newbody.
     If we encounter a fatal error we might return a now-empty body.

     Note, the returned ramp body is not 'popped', to be compatible with
     the way that decl.cc handles regular functions, the scope pop is done
     in the caller.  */

  tree newbody = push_stmt_list ();
  DECL_SAVED_TREE (orig) = newbody;

  /* If our original body is noexcept, then that's what we apply to our
     generated ramp, transfer any MUST_NOT_THOW_EXPR to that.  */
  bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
  if (is_noexcept)
    {
      /* The function body we will continue with is the single operand to
	 the must-not-throw.  */
      fnbody = TREE_OPERAND (body_start, 0);
      /* Transfer the must-not-throw to the ramp body.  */
      add_stmt (body_start);
      /* Re-start the ramp as must-not-throw.  */
      TREE_OPERAND (body_start, 0) = push_stmt_list ();
    }

  /* If the original function has a return value with a non-trivial DTOR
     and the body contains a var with a DTOR that might throw, the decl is
     marked "throwing_cleanup".
     We do not [in the ramp, which is synthesised here], use any body var
     types with DTORs that might throw.
     The original body is transformed into the actor function which only
     contains void returns, and is also wrapped in a try-catch block.
     So (a) the 'throwing_cleanup' is not correct for the ramp and (b) we do
     not need to transfer it to the actor which only contains void returns.  */
  cp_function_chain->throwing_cleanup = false;

  /* Create the coro frame type, as far as it can be known at this stage.
     1. Types we already know.  */

  tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
  tree handle_type = get_coroutine_handle_type (orig);
  tree promise_type = get_coroutine_promise_type (orig);

  /* 2. Types we need to define or look up.  */

  tree fr_name = get_fn_local_identifier (orig, "Frame");
  tree coro_frame_type = xref_tag (record_type, fr_name);
  DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope ();
  tree coro_frame_ptr = build_pointer_type (coro_frame_type);
  tree act_des_fn_type
    = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
  tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);

  /* Declare the actor and destroyer function.  */
  tree actor = coro_build_actor_or_destroy_function (orig, act_des_fn_type,
						     coro_frame_ptr, true);
  tree destroy = coro_build_actor_or_destroy_function (orig, act_des_fn_type,
						       coro_frame_ptr, false);

  /* Construct the wrapped function body; we will analyze this to determine
     the requirements for the coroutine frame.  */

  tree resume_idx_var = NULL_TREE;
  tree fs_label = NULL_TREE;
  hash_map<tree, param_info> *param_uses = analyze_fn_parms (orig);

  fnbody = coro_rewrite_function_body (fn_start, fnbody, orig, param_uses,
				       act_des_fn_ptr,
				       resume_idx_var, fs_label);
  /* Build our dummy coro frame layout.  */
  coro_frame_type = begin_class_definition (coro_frame_type);

  /* The fields for the coro frame.  */
  tree field_list = NULL_TREE;

  /* We need to know, and inspect, each suspend point in the function
     in several places.  It's convenient to place this map out of line
     since it's used from tree walk callbacks.  */
  suspend_points = new hash_map<tree, suspend_point_info>;

  /* Now insert the data for any body await points, at this time we also need
     to promote any temporaries that are captured by reference (to regular
     vars) they will get added to the coro frame along with other locals.  */
  susp_frame_data body_aw_points
    = {&field_list, handle_type, fs_label, NULL, NULL, 0, 0,
       hash_set<tree> (), NULL, NULL, 0, false, false, false};
  body_aw_points.block_stack = make_tree_vector ();
  body_aw_points.bind_stack = make_tree_vector ();
  body_aw_points.to_replace = make_tree_vector ();
  cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);

  /* 4. Now make space for local vars, this is conservative again, and we
     would expect to delete unused entries later.  */
  hash_map<tree, local_var_info> local_var_uses;
  local_vars_frame_data local_vars_data
    = {&field_list, &local_var_uses, 0, 0, fn_start, false, false};
  cp_walk_tree (&fnbody, register_local_var_uses, &local_vars_data, NULL);

  /* Tie off the struct for now, so that we can build offsets to the
     known entries.  */
  TYPE_FIELDS (coro_frame_type) = field_list;
  TYPE_BINFO (coro_frame_type) = make_tree_binfo (0);
  BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node;
  BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type;

  coro_frame_type = finish_struct (coro_frame_type, NULL_TREE);

  /* Ramp: */
  /* Now build the ramp function pieces.  */
  tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
  add_stmt (ramp_bind);
  tree ramp_body = push_stmt_list ();

  tree zeroinit = build1_loc (fn_start, CONVERT_EXPR,
			      coro_frame_ptr, integer_zero_node);
  tree coro_fp = coro_build_artificial_var (fn_start, "_Coro_frameptr",
					    coro_frame_ptr, orig, zeroinit);
  tree varlist = coro_fp;

  /* To signal that we need to cleanup copied function args.  */
  if (flag_exceptions && DECL_ARGUMENTS (orig))
    for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
	arg = DECL_CHAIN (arg))
      {
	param_info *parm_i = param_uses->get (arg);
	gcc_checking_assert (parm_i);
	if (parm_i->trivial_dtor)
	  continue;
	DECL_CHAIN (parm_i->guard_var) = varlist;
	varlist = parm_i->guard_var;
      }

  /* Signal that we need to clean up the promise object on exception.  */
  tree coro_promise_live
    = coro_build_artificial_var (fn_start, "_Coro_promise_live",
				 boolean_type_node, orig, boolean_false_node);
  DECL_CHAIN (coro_promise_live) = varlist;
  varlist = coro_promise_live;

  /* When the get-return-object is in the RETURN slot, we need to arrange for
     cleanup on exception.  */
  tree coro_gro_live
    = coro_build_artificial_var (fn_start, "_Coro_gro_live",
				 boolean_type_node, orig, boolean_false_node);

  DECL_CHAIN (coro_gro_live) = varlist;
  varlist = coro_gro_live;

  /* Collected the scope vars we need ... only one for now. */
  BIND_EXPR_VARS (ramp_bind) = nreverse (varlist);

  /* We're now going to create a new top level scope block for the ramp
     function.  */
  tree top_block = make_node (BLOCK);

  BIND_EXPR_BLOCK (ramp_bind) = top_block;
  BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind);
  BLOCK_SUBBLOCKS (top_block) = NULL_TREE;
  current_binding_level->blocks = top_block;

  /* The decl_expr for the coro frame pointer, initialize to zero so that we
     can pass it to the IFN_CO_FRAME (since there's no way to pass a type,
     directly apparently).  This avoids a "used uninitialized" warning.  */

  add_decl_expr (coro_fp);
  if (flag_exceptions && DECL_ARGUMENTS (orig))
    for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
	arg = DECL_CHAIN (arg))
      {
	param_info *parm_i = param_uses->get (arg);
	if (parm_i->trivial_dtor)
	  continue;
	add_decl_expr (parm_i->guard_var);;
      }
  add_decl_expr (coro_promise_live);
  add_decl_expr (coro_gro_live);

  /* The CO_FRAME internal function is a mechanism to allow the middle end
     to adjust the allocation in response to optimizations.  We provide the
     current conservative estimate of the frame size (as per the current)
     computed layout.  */
  tree frame_size = TYPE_SIZE_UNIT (coro_frame_type);
  tree resizeable
    = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2,
				    frame_size, coro_fp);

  /* [dcl.fct.def.coroutine] / 10 (part1)
    The unqualified-id get_return_object_on_allocation_failure is looked up
    in the scope of the promise type by class member access lookup.  */

  /* We don't require this, so coro_build_promise_expression can return NULL,
     but, if the lookup succeeds, then the function must be usable.  */
  tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig));
  tree grooaf
    = coro_build_promise_expression (orig, dummy_promise,
				     coro_gro_on_allocation_fail_identifier,
				     fn_start, NULL, /*musthave=*/false);

  /* however, should that fail, returning an error, the later stages can't
     handle the erroneous expression, so we reset the call as if it was
     absent.  */
  if (grooaf == error_mark_node)
    grooaf = NULL_TREE;

  /* Allocate the frame, this has several possibilities:
     [dcl.fct.def.coroutine] / 9 (part 1)
     The allocation function’s name is looked up in the scope of the promise
     type.  It's not a failure for it to be absent see part 4, below.  */

  tree nwname = ovl_op_identifier (false, NEW_EXPR);
  tree new_fn = NULL_TREE;

  if (TYPE_HAS_NEW_OPERATOR (promise_type))
    {
      tree fns = lookup_promise_method (orig, nwname, fn_start,
					/*musthave=*/true);
      /* [dcl.fct.def.coroutine] / 9 (part 2)
	If the lookup finds an allocation function in the scope of the promise
	type, overload resolution is performed on a function call created by
	assembling an argument list.  The first argument is the amount of space
	requested, and has type std::size_t.  The lvalues p1...pn are the
	succeeding arguments..  */
      vec<tree, va_gc> *args = make_tree_vector ();
      vec_safe_push (args, resizeable); /* Space needed.  */

      for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
	   arg = DECL_CHAIN (arg))
	{
	  param_info *parm_i = param_uses->get (arg);
	  gcc_checking_assert (parm_i);
	  if (parm_i->this_ptr || parm_i->lambda_cobj)
	    {
	      /* We pass a reference to *this to the allocator lookup.  */
	      tree tt = TREE_TYPE (TREE_TYPE (arg));
	      tree this_ref = build1 (INDIRECT_REF, tt, arg);
	      tt = cp_build_reference_type (tt, false);
	      this_ref = convert_to_reference (tt, this_ref, CONV_STATIC,
					       LOOKUP_NORMAL , NULL_TREE,
					       tf_warning_or_error);
	      vec_safe_push (args, convert_from_reference (this_ref));
	    }
	  else
	    vec_safe_push (args, convert_from_reference (arg));
	}

      /* Note the function selected; we test to see if it's NOTHROW.  */
      tree func;
      /* Failure is not an error for this attempt.  */
      new_fn = build_new_method_call (dummy_promise, fns, &args, NULL,
				      LOOKUP_NORMAL, &func, tf_none);
      release_tree_vector (args);

      if (new_fn == error_mark_node)
	{
	  /* [dcl.fct.def.coroutine] / 9 (part 3)
	    If no viable function is found, overload resolution is performed
	    again on a function call created by passing just the amount of
	    space required as an argument of type std::size_t.  */
	  args = make_tree_vector_single (resizeable); /* Space needed.  */
	  new_fn = build_new_method_call (dummy_promise, fns, &args,
					  NULL_TREE, LOOKUP_NORMAL, &func,
					  tf_none);
	  release_tree_vector (args);
	}

     /* However, if the promise provides an operator new, then one of these
	two options must be available.  */
    if (new_fn == error_mark_node)
      {
	error_at (fn_start, "%qE is provided by %qT but is not usable with"
		  " the function signature %qD", nwname, promise_type, orig);
	new_fn = error_mark_node;
      }
    else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func)))
      error_at (fn_start, "%qE is provided by %qT but %qE is not marked"
		" %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname);
    else if (!grooaf && TYPE_NOTHROW_P (TREE_TYPE (func)))
      warning_at (fn_start, 0, "%qE is marked %<throw()%> or %<noexcept%> but"
		  " no usable %<get_return_object_on_allocation_failure%>"
		  " is provided by %qT", nwname, promise_type);
    }
  else /* No operator new in the promise.  */
    {
      /* [dcl.fct.def.coroutine] / 9 (part 4)
	 If this lookup fails, the allocation function’s name is looked up in
	 the global scope.  */

      vec<tree, va_gc> *args;
      /* build_operator_new_call () will insert size needed as element 0 of
	 this, and we might need to append the std::nothrow constant.  */
      vec_alloc (args, 2);
      if (grooaf)
	{
	  /* [dcl.fct.def.coroutine] / 10 (part 2)
	   If any declarations (of the get return on allocation fail) are
	   found, then the result of a call to an allocation function used
	   to obtain storage for the coroutine state is assumed to return
	   nullptr if it fails to obtain storage and, if a global allocation
	   function is selected, the ::operator new(size_t, nothrow_t) form
	   is used.  The allocation function used in this case shall have a
	   non-throwing noexcept-specification.  So we need std::nothrow.  */
	  tree std_nt = lookup_qualified_name (std_node,
					       get_identifier ("nothrow"),
					       LOOK_want::NORMAL,
					       /*complain=*/true);
	  if (!std_nt || std_nt == error_mark_node)
	    error_at (fn_start, "%qE is provided by %qT but %<std::nothrow%> "
		      "cannot be found", grooaf, promise_type);
	  vec_safe_push (args, std_nt);
	}

      /* If we get to this point, we must succeed in looking up the global
	 operator new for the params provided.  Extract a simplified version
	 of the machinery from build_operator_new_call.  This can update the
	 frame size.  */
      tree cookie = NULL;
      new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie,
					/*align_arg=*/NULL,
					/*size_check=*/NULL, /*fn=*/NULL,
					tf_warning_or_error);
      resizeable = build_call_expr_internal_loc
	(fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp);
      /* If the operator call fails for some reason, then don't try to
	 amend it.  */
      if (new_fn != error_mark_node)
	CALL_EXPR_ARG (new_fn, 0) = resizeable;

      release_tree_vector (args);
    }

  tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn);
  tree r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, allocated);
  r = coro_build_cvt_void_expr_stmt (r, fn_start);
  add_stmt (r);

  /* If the user provided a method to return an object on alloc fail, then
     check the returned pointer and call the func if it's null.
     Otherwise, no check, and we fail for noexcept/fno-exceptions cases.  */

  if (grooaf)
    {
      /* [dcl.fct.def.coroutine] / 10 (part 3)
	 If the allocation function returns nullptr,the coroutine returns
	 control to the caller of the coroutine and the return value is
	 obtained by a call to T::get_return_object_on_allocation_failure(),
	 where T is the promise type.  */

      gcc_checking_assert (same_type_p (fn_return_type, TREE_TYPE (grooaf)));
      tree if_stmt = begin_if_stmt ();
      tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
      cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
      finish_if_stmt_cond (cond, if_stmt);
      if (VOID_TYPE_P (fn_return_type))
	{
	  /* Execute the get-return-object-on-alloc-fail call...  */
	  finish_expr_stmt (grooaf);
	  /* ... but discard the result, since we return void.  */
	  finish_return_stmt (NULL_TREE);
	}
      else
	{
	  /* Get the fallback return object.  */
	  r = build_cplus_new (fn_return_type, grooaf, tf_warning_or_error);
	  finish_return_stmt (r);
	}
      finish_then_clause (if_stmt);
      finish_if_stmt (if_stmt);
    }

  /* Up to now any exception thrown will propagate directly to the caller.
     This is OK since the only source of such exceptions would be in allocation
     of the coroutine frame, and therefore the ramp will not have initialized
     any further state.  From here, we will track state that needs explicit
     destruction in the case that promise or g.r.o setup fails or an exception
     is thrown from the initial suspend expression.  */
  tree ramp_cleanup = NULL_TREE;
  if (flag_exceptions)
    {
      ramp_cleanup = build_stmt (fn_start, TRY_BLOCK, NULL, NULL);
      add_stmt (ramp_cleanup);
      TRY_STMTS (ramp_cleanup) = push_stmt_list ();
    }

  /* deref the frame pointer, to use in member access code.  */
  tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error);

  /* For now, once allocation has succeeded we always assume that this needs
     destruction, there's no impl. for frame allocation elision.  */
  tree fnf_m = lookup_member (coro_frame_type, coro_frame_needs_free_id,
			      1, 0,tf_warning_or_error);
  tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE,
					       false, tf_warning_or_error);
  r = build2 (INIT_EXPR, boolean_type_node, fnf_x, boolean_true_node);
  r = coro_build_cvt_void_expr_stmt (r, fn_start);
  add_stmt (r);

  /* Put the resumer and destroyer functions in.  */

  tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor);
  tree resume_m
    = lookup_member (coro_frame_type, coro_resume_fn_id,
		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
  tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE,
						  false, tf_warning_or_error);
  r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, resume_x, actor_addr);
  finish_expr_stmt (r);

  tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy);
  tree destroy_m
    = lookup_member (coro_frame_type, coro_destroy_fn_id,
		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
  tree destroy_x
    = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false,
				      tf_warning_or_error);
  r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, destroy_x, destroy_addr);
  finish_expr_stmt (r);

  /* [dcl.fct.def.coroutine] /13
     When a coroutine is invoked, a copy is created for each coroutine
     parameter.  Each such copy is an object with automatic storage duration
     that is direct-initialized from an lvalue referring to the corresponding
     parameter if the parameter is an lvalue reference, and from an xvalue
     referring to it otherwise.  A reference to a parameter in the function-
     body of the coroutine and in the call to the coroutine promise
     constructor is replaced by a reference to its copy.  */

  vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs.  */

  /* The initialization and destruction of each parameter copy occurs in the
     context of the called coroutine.  Initializations of parameter copies are
     sequenced before the call to the coroutine promise constructor and
     indeterminately sequenced with respect to each other.  The lifetime of
     parameter copies ends immediately after the lifetime of the coroutine
     promise object ends.  */

  vec<tree, va_gc> *param_dtor_list = NULL;

  if (DECL_ARGUMENTS (orig))
    {
      promise_args = make_tree_vector ();
      for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
	   arg = DECL_CHAIN (arg))
	{
	  bool existed;
	  param_info &parm = param_uses->get_or_insert (arg, &existed);

	  tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
					/*protect=*/1, /*want_type=*/0,
					tf_warning_or_error);
	  tree fld_idx
	    = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE,
					      false, tf_warning_or_error);

	  /* Add this to the promise CTOR arguments list, accounting for
	     refs and special handling for method this ptr.  */
	  if (parm.this_ptr || parm.lambda_cobj)
	    {
	      /* We pass a reference to *this to the param preview.  */
	      tree tt = TREE_TYPE (arg);
	      gcc_checking_assert (POINTER_TYPE_P (tt));
	      tree ct = TREE_TYPE (tt);
	      tree this_ref = build1 (INDIRECT_REF, ct, arg);
	      tree rt = cp_build_reference_type (ct, false);
	      this_ref = convert_to_reference (rt, this_ref, CONV_STATIC,
					       LOOKUP_NORMAL, NULL_TREE,
					       tf_warning_or_error);
	      vec_safe_push (promise_args, this_ref);
	    }
	  else if (parm.rv_ref)
	    vec_safe_push (promise_args, move (fld_idx));
	  else
	    vec_safe_push (promise_args, fld_idx);

	  if (parm.rv_ref || parm.pt_ref)
	    /* Initialise the frame reference field directly.  */
	    r = cp_build_modify_expr (fn_start, TREE_OPERAND (fld_idx, 0),
				      INIT_EXPR, arg, tf_warning_or_error);
	  else
	    {
	      r = forward_parm (arg);
	      r = cp_build_modify_expr (fn_start, fld_idx, INIT_EXPR, r,
					tf_warning_or_error);
	    }
	  finish_expr_stmt (r);
	  if (!parm.trivial_dtor)
	    {
	      if (param_dtor_list == NULL)
		param_dtor_list = make_tree_vector ();
	      vec_safe_push (param_dtor_list, parm.field_id);
	      /* Cleanup this frame copy on exception.  */
	      parm.fr_copy_dtor
		= build_special_member_call (fld_idx, complete_dtor_identifier,
					     NULL, parm.frame_type,
					     LOOKUP_NORMAL,
					     tf_warning_or_error);
	      if (flag_exceptions)
		{
		  /* This var is now live.  */
		  r = build_modify_expr (fn_start, parm.guard_var,
					 boolean_type_node, INIT_EXPR, fn_start,
					 boolean_true_node, boolean_type_node);
		  finish_expr_stmt (r);
		}
	    }
	}
    }

  /* Set up the promise.  */
  tree promise_m
    = lookup_member (coro_frame_type, coro_promise_id,
		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);

  tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
					   false, tf_warning_or_error);

  tree promise_dtor = NULL_TREE;
  if (type_build_ctor_call (promise_type))
    {
      /* Do a placement new constructor for the promise type (we never call
	 the new operator, just the constructor on the object in place in the
	 frame).

	 First try to find a constructor with the same parameter list as the
	 original function (if it has params), failing that find a constructor
	 with no parameter list.  */

      if (DECL_ARGUMENTS (orig))
	{
	  r = build_special_member_call (p, complete_ctor_identifier,
					 &promise_args, promise_type,
					 LOOKUP_NORMAL, tf_none);
	  release_tree_vector (promise_args);
	}
      else
	r = NULL_TREE;

      if (r == NULL_TREE || r == error_mark_node)
	r = build_special_member_call (p, complete_ctor_identifier, NULL,
				       promise_type, LOOKUP_NORMAL,
				       tf_warning_or_error);

      r = coro_build_cvt_void_expr_stmt (r, fn_start);
      finish_expr_stmt (r);

      r = build_modify_expr (fn_start, coro_promise_live, boolean_type_node,
			     INIT_EXPR, fn_start, boolean_true_node,
			     boolean_type_node);
      finish_expr_stmt (r);

      promise_dtor
	= build_special_member_call (p, complete_dtor_identifier,
				     NULL, promise_type, LOOKUP_NORMAL,
				     tf_warning_or_error);
    }

  /* Set up a new bind context for the GRO.  */
  tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
  /* Make and connect the scope blocks.  */
  tree gro_block = make_node (BLOCK);
  BLOCK_SUPERCONTEXT (gro_block) = top_block;
  BLOCK_SUBBLOCKS (top_block) = gro_block;
  BIND_EXPR_BLOCK (gro_context_bind) = gro_block;
  add_stmt (gro_context_bind);

  tree get_ro
    = coro_build_promise_expression (orig, p,
				     coro_get_return_object_identifier,
				     fn_start, NULL, /*musthave=*/true);
  /* Without a return object we haven't got much clue what's going on.  */
  if (get_ro == error_mark_node)
    {
      BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
      DECL_SAVED_TREE (orig) = newbody;
      /* Suppress warnings about the missing return value.  */
      suppress_warning (orig, OPT_Wreturn_type);
      return false;
    }

  tree gro_context_body = push_stmt_list ();
  tree gro_type = TREE_TYPE (get_ro);
  bool gro_is_void_p = VOID_TYPE_P (gro_type);

  tree gro = NULL_TREE;
  tree gro_bind_vars = NULL_TREE;
  /* Used for return objects in the RESULT slot.  */
  tree gro_ret_dtor = NULL_TREE;
  tree gro_cleanup_stmt = NULL_TREE;
  /* We have to sequence the call to get_return_object before initial
     suspend.  */
  if (gro_is_void_p)
    r = get_ro;
  else if (same_type_p (gro_type, fn_return_type))
    {
     /* [dcl.fct.def.coroutine] / 7
	The expression promise.get_return_object() is used to initialize the
	glvalue result or... (see below)
	Construct the return result directly.  */
      if (type_build_ctor_call (gro_type))
	{
	  vec<tree, va_gc> *arg = make_tree_vector_single (get_ro);
	  r = build_special_member_call (DECL_RESULT (orig),
					 complete_ctor_identifier,
					 &arg, gro_type, LOOKUP_NORMAL,
					 tf_warning_or_error);
	  release_tree_vector (arg);
	}
      else
	r = build2_loc (fn_start, INIT_EXPR, gro_type,
			DECL_RESULT (orig), get_ro);

      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (gro_type))
	/* If some part of the initalization code (prior to the await_resume
	     of the initial suspend expression), then we need to clean up the
	     return value.  */
	gro_ret_dtor
	  = build_special_member_call (DECL_RESULT (orig),
				       complete_dtor_identifier, NULL,
				       gro_type, LOOKUP_NORMAL,
				       tf_warning_or_error);
    }
  else
    {
      /* ... or ... Construct an object that will be used as the single
	param to the CTOR for the return object.  */
      gro = coro_build_artificial_var (fn_start, "_Coro_gro", gro_type, orig,
				       NULL_TREE);
      add_decl_expr (gro);
      gro_bind_vars = gro;
      r = cp_build_modify_expr (input_location, gro, INIT_EXPR, get_ro,
				tf_warning_or_error);
      /* The constructed object might require a cleanup.  */
      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (gro_type))
	{
	  gro_cleanup_stmt
	    = build_special_member_call (gro, complete_dtor_identifier,
					 NULL, gro_type, LOOKUP_NORMAL,
					 tf_warning_or_error);
	  gro_cleanup_stmt = build_stmt (input_location, CLEANUP_STMT, NULL,
					 gro_cleanup_stmt, gro);
	}
    }
  finish_expr_stmt (r);

  if (gro_cleanup_stmt && gro_cleanup_stmt != error_mark_node)
    CLEANUP_BODY (gro_cleanup_stmt) = push_stmt_list ();

  /* If we have a live g.r.o in the return slot, then signal this for exception
     cleanup.  */
  if (gro_ret_dtor)
    {
       r = build_modify_expr (fn_start, coro_gro_live, boolean_type_node,
			      INIT_EXPR, fn_start, boolean_true_node,
			      boolean_type_node);
      finish_expr_stmt (r);
    }
  /* Initialize the resume_idx_var to 0, meaning "not started".  */
  tree resume_idx_m
    = lookup_member (coro_frame_type, coro_resume_index_id,
		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
  tree resume_idx
    = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false,
				      tf_warning_or_error);
  r = build_int_cst (short_unsigned_type_node, 0);
  r = build2_loc (fn_start, INIT_EXPR, short_unsigned_type_node, resume_idx, r);
  r = coro_build_cvt_void_expr_stmt (r, fn_start);
  add_stmt (r);

  /* So .. call the actor ..  */
  r = build_call_expr_loc (fn_start, actor, 1, coro_fp);
  r = maybe_cleanup_point_expr_void (r);
  add_stmt (r);

  /* Switch to using 'input_location' as the loc, since we're now more
     logically doing things related to the end of the function.  */

  /* The ramp is done, we just need the return value.
     [dcl.fct.def.coroutine] / 7
     The expression promise.get_return_object() is used to initialize the
     glvalue result or prvalue result object of a call to a coroutine.

     If the 'get return object' is non-void, then we built it before the
     promise was constructed.  We now supply a reference to that var,
     either as the return value (if it's the same type) or to the CTOR
     for an object of the return type.  */

  if (same_type_p (gro_type, fn_return_type))
    r = gro_is_void_p ? NULL_TREE : DECL_RESULT (orig);
  else if (!gro_is_void_p)
    /* check_return_expr will automatically return gro as an rvalue via
       treat_lvalue_as_rvalue_p.  */
    r = gro;
  else if (CLASS_TYPE_P (fn_return_type))
    {
      /* For class type return objects, we can attempt to construct,
	 even if the gro is void. ??? Citation ??? c++/100476  */
      r = build_special_member_call (NULL_TREE,
				     complete_ctor_identifier, NULL,
				     fn_return_type, LOOKUP_NORMAL,
				     tf_warning_or_error);
      r = build_cplus_new (fn_return_type, r, tf_warning_or_error);
    }
  else
    {
      /* We can't initialize a non-class return value from void.  */
      error_at (input_location, "cannot initialize a return object of type"
		" %qT with an rvalue of type %<void%>", fn_return_type);
      r = error_mark_node;
    }

  finish_return_stmt (r);

  if (gro_cleanup_stmt)
    {
      CLEANUP_BODY (gro_cleanup_stmt)
	= pop_stmt_list (CLEANUP_BODY (gro_cleanup_stmt));
      add_stmt (gro_cleanup_stmt);
    }

  /* Finish up the ramp function.  */
  BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
  BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
  TREE_SIDE_EFFECTS (gro_context_bind) = true;

  if (flag_exceptions)
    {
      TRY_HANDLERS (ramp_cleanup) = push_stmt_list ();
      tree handler = begin_handler ();
      finish_handler_parms (NULL_TREE, handler); /* catch (...) */

      /* If we have a live G.R.O in the return slot, then run its DTOR.
     When the return object is constructed from a separate g.r.o, this is
     already handled by its regular cleanup.  */
      if (gro_ret_dtor && gro_ret_dtor != error_mark_node)
	{
	  tree gro_d_if = begin_if_stmt ();
	  finish_if_stmt_cond (coro_gro_live, gro_d_if);
	  finish_expr_stmt (gro_ret_dtor);
	  finish_then_clause (gro_d_if);
	  tree gro_d_if_scope = IF_SCOPE (gro_d_if);
	  IF_SCOPE (gro_d_if) = NULL;
	  gro_d_if = do_poplevel (gro_d_if_scope);
	  add_stmt (gro_d_if);
	}

      /* If the promise is live, then run its dtor if that's available.  */
      if (promise_dtor && promise_dtor != error_mark_node)
	{
	  tree promise_d_if = begin_if_stmt ();
	  finish_if_stmt_cond (coro_promise_live, promise_d_if);
	  finish_expr_stmt (promise_dtor);
	  finish_then_clause (promise_d_if);
	  tree promise_d_if_scope = IF_SCOPE (promise_d_if);
	  IF_SCOPE (promise_d_if) = NULL;
	  promise_d_if = do_poplevel (promise_d_if_scope);
	  add_stmt (promise_d_if);
	}

      /* Clean up any frame copies of parms with non-trivial dtors.  */
      if (DECL_ARGUMENTS (orig))
	for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
	     arg = DECL_CHAIN (arg))
	  {
	    param_info *parm_i = param_uses->get (arg);
	    if (parm_i->trivial_dtor)
	      continue;
	    if (parm_i->fr_copy_dtor && parm_i->fr_copy_dtor != error_mark_node)
	      {
		tree dtor_if = begin_if_stmt ();
		finish_if_stmt_cond (parm_i->guard_var, dtor_if);
		finish_expr_stmt (parm_i->fr_copy_dtor);
		finish_then_clause (dtor_if);
		tree parm_d_if_scope = IF_SCOPE (dtor_if);
		IF_SCOPE (dtor_if) = NULL;
		dtor_if = do_poplevel (parm_d_if_scope);
		add_stmt (dtor_if);
	      }
	  }

      /* We always expect to delete the frame.  */
      tree del_coro_fr = coro_get_frame_dtor (coro_fp, orig, frame_size,
					      promise_type, fn_start);
      finish_expr_stmt (del_coro_fr);
      tree rethrow = build_throw (fn_start, NULL_TREE);
      suppress_warning (rethrow);
      finish_expr_stmt (rethrow);
      finish_handler (handler);
      TRY_HANDLERS (ramp_cleanup) = pop_stmt_list (TRY_HANDLERS (ramp_cleanup));
    }

  BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
  TREE_SIDE_EFFECTS (ramp_bind) = true;

  /* Start to build the final functions.

     We push_deferring_access_checks to avoid these routines being seen as
     nested by the middle end; we are doing the outlining here.  */

  push_deferring_access_checks (dk_no_check);

  /* Build the actor...  */
  build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig,
		  &local_var_uses, param_dtor_list,
		  resume_idx_var, body_aw_points.await_number, frame_size);

  /* Destroyer ... */
  build_destroy_fn (fn_start, coro_frame_type, destroy, actor);

  pop_deferring_access_checks ();

  DECL_SAVED_TREE (orig) = newbody;
  /* Link our new functions into the list.  */
  TREE_CHAIN (destroy) = TREE_CHAIN (orig);
  TREE_CHAIN (actor) = destroy;
  TREE_CHAIN (orig) = actor;

  *resumer = actor;
  *destroyer = destroy;

  delete suspend_points;
  suspend_points = NULL;
  return true;
}

#include "gt-cp-coroutines.h"

