1/* coroutine-specific state, expansions and tests.
2
3   Copyright (C) 2018-2022 Free Software Foundation, Inc.
4
5 Contributed by Iain Sandoe <iain@sandoe.co.uk> under contract to Facebook.
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
20along with GCC; see the file COPYING3.  If not see
21<http://www.gnu.org/licenses/>.  */
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "target.h"
27#include "cp-tree.h"
28#include "stringpool.h"
29#include "stmt.h"
30#include "stor-layout.h"
31#include "tree-iterator.h"
32#include "tree.h"
33#include "gcc-rich-location.h"
34#include "hash-map.h"
35
36static bool coro_promise_type_found_p (tree, location_t);
37
38/* GCC C++ coroutines implementation.
39
40  The user authors a function that becomes a coroutine (lazily) by
41  making use of any of the co_await, co_yield or co_return keywords.
42
43  Unlike a regular function, where the activation record is placed on the
44  stack, and is destroyed on function exit, a coroutine has some state that
45  persists between calls - the coroutine frame (analogous to a stack frame).
46
47  We transform the user's function into three pieces:
48  1. A so-called ramp function, that establishes the coroutine frame and
49     begins execution of the coroutine.
50  2. An actor function that contains the state machine corresponding to the
51     user's suspend/resume structure.
52  3. A stub function that calls the actor function in 'destroy' mode.
53
54  The actor function is executed:
55   * from "resume point 0" by the ramp.
56   * from resume point N ( > 0 ) for handle.resume() calls.
57   * from the destroy stub for destroy point N for handle.destroy() calls.
58
59  The functions in this file carry out the necessary analysis of, and
60  transforms to, the AST to perform this.
61
62  The C++ coroutine design makes use of some helper functions that are
63  authored in a so-called "promise" class provided by the user.
64
65  At parse time (or post substitution) the type of the coroutine promise
66  will be determined.  At that point, we can look up the required promise
67  class methods and issue diagnostics if they are missing or incorrect.  To
68  avoid repeating these actions at code-gen time, we make use of temporary
69  'proxy' variables for the coroutine handle and the promise - which will
70  eventually be instantiated in the coroutine frame.
71
72  Each of the keywords will expand to a code sequence (although co_yield is
73  just syntactic sugar for a co_await).
74
75  We defer the analysis and transformation until template expansion is
76  complete so that we have complete types at that time.  */
77
78
79/* The state that we collect during parsing (and template expansion) for
80   a coroutine.  */
81
82struct GTY((for_user)) coroutine_info
83{
84  tree function_decl; /* The original function decl.  */
85  tree actor_decl;    /* The synthesized actor function.  */
86  tree destroy_decl;  /* The synthesized destroy function.  */
87  tree promise_type;  /* The cached promise type for this function.  */
88  tree handle_type;   /* The cached coroutine handle for this function.  */
89  tree self_h_proxy;  /* A handle instance that is used as the proxy for the
90			 one that will eventually be allocated in the coroutine
91			 frame.  */
92  tree promise_proxy; /* Likewise, a proxy promise instance.  */
93  tree return_void;   /* The expression for p.return_void() if it exists.  */
94  location_t first_coro_keyword; /* The location of the keyword that made this
95				    function into a coroutine.  */
96  /* Flags to avoid repeated errors for per-function issues.  */
97  bool coro_ret_type_error_emitted;
98  bool coro_promise_error_emitted;
99  bool coro_co_return_error_emitted;
100};
101
102struct coroutine_info_hasher : ggc_ptr_hash<coroutine_info>
103{
104  typedef tree compare_type; /* We only compare the function decl.  */
105  static inline hashval_t hash (coroutine_info *);
106  static inline hashval_t hash (const compare_type &);
107  static inline bool equal (coroutine_info *, coroutine_info *);
108  static inline bool equal (coroutine_info *, const compare_type &);
109};
110
111/* This table holds all the collected coroutine state for coroutines in
112   the current translation unit.  */
113
114static GTY (()) hash_table<coroutine_info_hasher> *coroutine_info_table;
115
116/* We will initialize state lazily.  */
117static bool coro_initialized = false;
118
119/* Return a hash value for the entry pointed to by INFO.
120   The compare type is a tree, but the only trees we are going use are
121   function decls.  We use the DECL_UID as the hash value since that is
122   stable across PCH.  */
123
124hashval_t
125coroutine_info_hasher::hash (coroutine_info *info)
126{
127  return DECL_UID (info->function_decl);
128}
129
130/* Return a hash value for the compare value COMP.  */
131
132hashval_t
133coroutine_info_hasher::hash (const compare_type& comp)
134{
135  return DECL_UID (comp);
136}
137
138/* Return true if the entries pointed to by LHS and RHS are for the
139   same coroutine.  */
140
141bool
142coroutine_info_hasher::equal (coroutine_info *lhs, coroutine_info *rhs)
143{
144  return lhs->function_decl == rhs->function_decl;
145}
146
147bool
148coroutine_info_hasher::equal (coroutine_info *lhs, const compare_type& rhs)
149{
150  return lhs->function_decl == rhs;
151}
152
153/* Get the existing coroutine_info for FN_DECL, or insert a new one if the
154   entry does not yet exist.  */
155
156coroutine_info *
157get_or_insert_coroutine_info (tree fn_decl)
158{
159  gcc_checking_assert (coroutine_info_table != NULL);
160
161  coroutine_info **slot = coroutine_info_table->find_slot_with_hash
162    (fn_decl, coroutine_info_hasher::hash (fn_decl), INSERT);
163
164  if (*slot == NULL)
165    {
166      *slot = new (ggc_cleared_alloc<coroutine_info> ()) coroutine_info ();
167      (*slot)->function_decl = fn_decl;
168    }
169
170  return *slot;
171}
172
173/* Get the existing coroutine_info for FN_DECL, fail if it doesn't exist.  */
174
175coroutine_info *
176get_coroutine_info (tree fn_decl)
177{
178  if (coroutine_info_table == NULL)
179    return NULL;
180
181  coroutine_info **slot = coroutine_info_table->find_slot_with_hash
182    (fn_decl, coroutine_info_hasher::hash (fn_decl), NO_INSERT);
183  if (slot)
184    return *slot;
185  return NULL;
186}
187
188/* We will lazily create all the identifiers that are used by coroutines
189   on the first attempt to lookup the traits.  */
190
191/* Identifiers that are used by all coroutines.  */
192
193static GTY(()) tree coro_traits_identifier;
194static GTY(()) tree coro_handle_identifier;
195static GTY(()) tree coro_promise_type_identifier;
196
197/* Required promise method name identifiers.  */
198
199static GTY(()) tree coro_await_transform_identifier;
200static GTY(()) tree coro_initial_suspend_identifier;
201static GTY(()) tree coro_final_suspend_identifier;
202static GTY(()) tree coro_return_void_identifier;
203static GTY(()) tree coro_return_value_identifier;
204static GTY(()) tree coro_yield_value_identifier;
205static GTY(()) tree coro_resume_identifier;
206static GTY(()) tree coro_address_identifier;
207static GTY(()) tree coro_from_address_identifier;
208static GTY(()) tree coro_get_return_object_identifier;
209static GTY(()) tree coro_gro_on_allocation_fail_identifier;
210static GTY(()) tree coro_unhandled_exception_identifier;
211
212/* Awaitable methods.  */
213
214static GTY(()) tree coro_await_ready_identifier;
215static GTY(()) tree coro_await_suspend_identifier;
216static GTY(()) tree coro_await_resume_identifier;
217
218/* Accessors for the coroutine frame state used by the implementation.  */
219
220static GTY(()) tree coro_resume_fn_id;
221static GTY(()) tree coro_destroy_fn_id;
222static GTY(()) tree coro_promise_id;
223static GTY(()) tree coro_frame_needs_free_id;
224static GTY(()) tree coro_resume_index_id;
225static GTY(()) tree coro_self_handle_id;
226static GTY(()) tree coro_actor_continue_id;
227static GTY(()) tree coro_frame_i_a_r_c_id;
228
229/* Create the identifiers used by the coroutines library interfaces and
230   the implementation frame state.  */
231
232static void
233coro_init_identifiers ()
234{
235  coro_traits_identifier = get_identifier ("coroutine_traits");
236  coro_handle_identifier = get_identifier ("coroutine_handle");
237  coro_promise_type_identifier = get_identifier ("promise_type");
238
239  coro_await_transform_identifier = get_identifier ("await_transform");
240  coro_initial_suspend_identifier = get_identifier ("initial_suspend");
241  coro_final_suspend_identifier = get_identifier ("final_suspend");
242  coro_return_void_identifier = get_identifier ("return_void");
243  coro_return_value_identifier = get_identifier ("return_value");
244  coro_yield_value_identifier = get_identifier ("yield_value");
245  coro_resume_identifier = get_identifier ("resume");
246  coro_address_identifier = get_identifier ("address");
247  coro_from_address_identifier = get_identifier ("from_address");
248  coro_get_return_object_identifier = get_identifier ("get_return_object");
249  coro_gro_on_allocation_fail_identifier =
250    get_identifier ("get_return_object_on_allocation_failure");
251  coro_unhandled_exception_identifier = get_identifier ("unhandled_exception");
252
253  coro_await_ready_identifier = get_identifier ("await_ready");
254  coro_await_suspend_identifier = get_identifier ("await_suspend");
255  coro_await_resume_identifier = get_identifier ("await_resume");
256
257  /* Coroutine state frame field accessors.  */
258  coro_resume_fn_id = get_identifier ("_Coro_resume_fn");
259  coro_destroy_fn_id = get_identifier ("_Coro_destroy_fn");
260  coro_promise_id = get_identifier ("_Coro_promise");
261  coro_frame_needs_free_id = get_identifier ("_Coro_frame_needs_free");
262  coro_frame_i_a_r_c_id = get_identifier ("_Coro_initial_await_resume_called");
263  coro_resume_index_id = get_identifier ("_Coro_resume_index");
264  coro_self_handle_id = get_identifier ("_Coro_self_handle");
265  coro_actor_continue_id = get_identifier ("_Coro_actor_continue");
266}
267
268/* Trees we only need to set up once.  */
269
270static GTY(()) tree coro_traits_templ;
271static GTY(()) tree coro_handle_templ;
272static GTY(()) tree void_coro_handle_type;
273
274/* ================= Parse, Semantics and Type checking ================= */
275
276/* This initial set of routines are helper for the parsing and template
277   expansion phases.
278
279   At the completion of this, we will have completed trees for each of the
280   keywords, but making use of proxy variables for the self-handle and the
281   promise class instance.  */
282
283/* [coroutine.traits]
284   Lookup the coroutine_traits template decl.  */
285
286static tree
287find_coro_traits_template_decl (location_t kw)
288{
289  /* If we are missing fundamental information, such as the traits, (or the
290     declaration found is not a type template), then don't emit an error for
291     every keyword in a TU, just do it once.  */
292  static bool traits_error_emitted = false;
293
294  tree traits_decl = lookup_qualified_name (std_node, coro_traits_identifier,
295					    LOOK_want::NORMAL,
296					    /*complain=*/!traits_error_emitted);
297  if (traits_decl == error_mark_node
298      || !DECL_TYPE_TEMPLATE_P (traits_decl))
299    {
300      if (!traits_error_emitted)
301	{
302	  gcc_rich_location richloc (kw);
303	  error_at (&richloc, "coroutines require a traits template; cannot"
304		    " find %<%E::%E%>", std_node, coro_traits_identifier);
305	  inform (&richloc, "perhaps %<#include <coroutine>%> is missing");
306	  traits_error_emitted = true;
307	}
308      return NULL_TREE;
309    }
310  else
311    return traits_decl;
312}
313
314/*  Instantiate Coroutine traits for the function signature.  */
315
316static tree
317instantiate_coro_traits (tree fndecl, location_t kw)
318{
319  /* [coroutine.traits.primary]
320     So now build up a type list for the template <typename _R, typename...>.
321     The types are the function's arg types and _R is the function return
322     type.  */
323
324  tree functyp = TREE_TYPE (fndecl);
325  tree arg = DECL_ARGUMENTS (fndecl);
326  tree arg_node = TYPE_ARG_TYPES (functyp);
327  tree argtypes = make_tree_vec (list_length (arg_node)-1);
328  unsigned p = 0;
329
330  while (arg_node != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (arg_node)))
331    {
332      if (is_this_parameter (arg)
333	  || DECL_NAME (arg) == closure_identifier)
334	{
335	  /* We pass a reference to *this to the param preview.  */
336	  tree ct = TREE_TYPE (TREE_TYPE (arg));
337	  TREE_VEC_ELT (argtypes, p++) = cp_build_reference_type (ct, false);
338	}
339      else
340	TREE_VEC_ELT (argtypes, p++) = TREE_VALUE (arg_node);
341
342      arg_node = TREE_CHAIN (arg_node);
343      arg = DECL_CHAIN (arg);
344    }
345
346  tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
347  SET_ARGUMENT_PACK_ARGS (argtypepack, argtypes);
348
349  tree targ = make_tree_vec (2);
350  TREE_VEC_ELT (targ, 0) = TREE_TYPE (functyp);
351  TREE_VEC_ELT (targ, 1) = argtypepack;
352
353  tree traits_class
354    = lookup_template_class (coro_traits_templ, targ,
355			     /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE,
356			     /*entering scope=*/false, tf_warning_or_error);
357
358  if (traits_class == error_mark_node)
359    {
360      error_at (kw, "cannot instantiate %<coroutine traits%>");
361      return NULL_TREE;
362    }
363
364  return traits_class;
365}
366
367/* [coroutine.handle] */
368
369static tree
370find_coro_handle_template_decl (location_t kw)
371{
372  /* As for the coroutine traits, this error is per TU, so only emit
373    it once.  */
374  static bool coro_handle_error_emitted = false;
375  tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier,
376					    LOOK_want::NORMAL,
377					    !coro_handle_error_emitted);
378  if (handle_decl == error_mark_node
379      || !DECL_CLASS_TEMPLATE_P (handle_decl))
380    {
381      if (!coro_handle_error_emitted)
382	error_at (kw, "coroutines require a handle class template;"
383		  " cannot find %<%E::%E%>", std_node, coro_handle_identifier);
384      coro_handle_error_emitted = true;
385      return NULL_TREE;
386    }
387  else
388    return handle_decl;
389}
390
391/* Instantiate the handle template for a given promise type.  */
392
393static tree
394instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type)
395{
396  /* So now build up a type list for the template, one entry, the promise.  */
397  tree targ = make_tree_vec (1);
398  TREE_VEC_ELT (targ, 0) = promise_type;
399  tree handle_type
400    = lookup_template_class (coro_handle_identifier, targ,
401			     /* in_decl=*/NULL_TREE,
402			     /* context=*/std_node,
403			     /* entering scope=*/false, tf_warning_or_error);
404
405  if (handle_type == error_mark_node)
406    {
407      error_at (kw, "cannot instantiate a %<coroutine handle%> for"
408		" promise type %qT", promise_type);
409      return NULL_TREE;
410    }
411
412  return handle_type;
413}
414
415/* Look for the promise_type in the instantiated traits.  */
416
417static tree
418find_promise_type (tree traits_class)
419{
420  tree promise_type
421    = lookup_member (traits_class, coro_promise_type_identifier,
422		     /* protect=*/1, /*want_type=*/true, tf_warning_or_error);
423
424  if (promise_type)
425    promise_type
426      = complete_type_or_else (TREE_TYPE (promise_type), promise_type);
427
428  /* NULL_TREE on fail.  */
429  return promise_type;
430}
431
432static bool
433coro_promise_type_found_p (tree fndecl, location_t loc)
434{
435  gcc_assert (fndecl != NULL_TREE);
436
437  if (!coro_initialized)
438    {
439      /* Trees we only need to create once.
440	 Set up the identifiers we will use.  */
441      coro_init_identifiers ();
442
443      /* Coroutine traits template.  */
444      coro_traits_templ = find_coro_traits_template_decl (loc);
445      if (coro_traits_templ == NULL_TREE)
446	return false;
447
448      /*  coroutine_handle<> template.  */
449      coro_handle_templ = find_coro_handle_template_decl (loc);
450      if (coro_handle_templ == NULL_TREE)
451	return false;
452
453      /*  We can also instantiate the void coroutine_handle<>  */
454      void_coro_handle_type =
455	instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
456      if (void_coro_handle_type == NULL_TREE)
457	return false;
458
459      /* A table to hold the state, per coroutine decl.  */
460      gcc_checking_assert (coroutine_info_table == NULL);
461      coroutine_info_table =
462	hash_table<coroutine_info_hasher>::create_ggc (11);
463
464      if (coroutine_info_table == NULL)
465	return false;
466
467      coro_initialized = true;
468    }
469
470  /* Save the coroutine data on the side to avoid the overhead on every
471     function decl tree.  */
472
473  coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
474  /* Without this, we cannot really proceed.  */
475  gcc_checking_assert (coro_info);
476
477  /* If we don't already have a current promise type, try to look it up.  */
478  if (coro_info->promise_type == NULL_TREE)
479    {
480      /* Get the coroutine traits template class instance for the function
481	 signature we have - coroutine_traits <R, ...>  */
482
483      tree templ_class = instantiate_coro_traits (fndecl, loc);
484
485      /* Find the promise type for that.  */
486      coro_info->promise_type = find_promise_type (templ_class);
487
488      /* If we don't find it, punt on the rest.  */
489      if (coro_info->promise_type == NULL_TREE)
490	{
491	  if (!coro_info->coro_promise_error_emitted)
492	    error_at (loc, "unable to find the promise type for"
493		      " this coroutine");
494	  coro_info->coro_promise_error_emitted = true;
495	  return false;
496	}
497
498      /* Test for errors in the promise type that can be determined now.  */
499      tree has_ret_void = lookup_member (coro_info->promise_type,
500					 coro_return_void_identifier,
501					 /*protect=*/1, /*want_type=*/0,
502					 tf_none);
503      tree has_ret_val = lookup_member (coro_info->promise_type,
504					coro_return_value_identifier,
505					/*protect=*/1, /*want_type=*/0,
506					tf_none);
507      if (has_ret_void && has_ret_val)
508	{
509	  location_t ploc = DECL_SOURCE_LOCATION (fndecl);
510	  if (!coro_info->coro_co_return_error_emitted)
511	    error_at (ploc, "the coroutine promise type %qT declares both"
512		      " %<return_value%> and %<return_void%>",
513		      coro_info->promise_type);
514	  inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_void)),
515		  "%<return_void%> declared here");
516	  has_ret_val = BASELINK_FUNCTIONS (has_ret_val);
517	  const char *message = "%<return_value%> declared here";
518	  if (TREE_CODE (has_ret_val) == OVERLOAD)
519	    {
520	      has_ret_val = OVL_FIRST (has_ret_val);
521	      message = "%<return_value%> first declared here";
522	    }
523	  inform (DECL_SOURCE_LOCATION (has_ret_val), message);
524	  coro_info->coro_co_return_error_emitted = true;
525	  return false;
526	}
527
528      /* Try to find the handle type for the promise.  */
529      tree handle_type =
530	instantiate_coro_handle_for_promise_type (loc, coro_info->promise_type);
531      if (handle_type == NULL_TREE)
532	return false;
533
534      /* Complete this, we're going to use it.  */
535      coro_info->handle_type = complete_type_or_else (handle_type, fndecl);
536
537      /* Diagnostic would be emitted by complete_type_or_else.  */
538      if (!coro_info->handle_type)
539	return false;
540
541      /* Build a proxy for a handle to "self" as the param to
542	 await_suspend() calls.  */
543      coro_info->self_h_proxy
544	= build_lang_decl (VAR_DECL, coro_self_handle_id,
545			   coro_info->handle_type);
546
547      /* Build a proxy for the promise so that we can perform lookups.  */
548      coro_info->promise_proxy
549	= build_lang_decl (VAR_DECL, coro_promise_id,
550			   coro_info->promise_type);
551
552      /* Note where we first saw a coroutine keyword.  */
553      coro_info->first_coro_keyword = loc;
554    }
555
556  return true;
557}
558
559/* Map from actor or destroyer to ramp.  */
560static GTY(()) hash_map<tree, tree> *to_ramp;
561
562/* Given a tree that is an actor or destroy, find the ramp function.  */
563
564tree
565coro_get_ramp_function (tree decl)
566{
567  if (!to_ramp)
568    return NULL_TREE;
569  tree *p = to_ramp->get (decl);
570  if (p)
571    return *p;
572  return NULL_TREE;
573}
574
575/* Given the DECL for a ramp function (the user's original declaration) return
576   the actor function if it has been defined.  */
577
578tree
579coro_get_actor_function (tree decl)
580{
581  if (coroutine_info *info = get_coroutine_info (decl))
582    return info->actor_decl;
583
584  return NULL_TREE;
585}
586
587/* Given the DECL for a ramp function (the user's original declaration) return
588   the destroy function if it has been defined.  */
589
590tree
591coro_get_destroy_function (tree decl)
592{
593  if (coroutine_info *info = get_coroutine_info (decl))
594    return info->destroy_decl;
595
596  return NULL_TREE;
597}
598
599/* These functions assumes that the caller has verified that the state for
600   the decl has been initialized, we try to minimize work here.  */
601
602static tree
603get_coroutine_promise_type (tree decl)
604{
605  if (coroutine_info *info = get_coroutine_info (decl))
606    return info->promise_type;
607
608  return NULL_TREE;
609}
610
611static tree
612get_coroutine_handle_type (tree decl)
613{
614  if (coroutine_info *info = get_coroutine_info (decl))
615    return info->handle_type;
616
617  return NULL_TREE;
618}
619
620static tree
621get_coroutine_self_handle_proxy (tree decl)
622{
623  if (coroutine_info *info = get_coroutine_info (decl))
624    return info->self_h_proxy;
625
626  return NULL_TREE;
627}
628
629static tree
630get_coroutine_promise_proxy (tree decl)
631{
632  if (coroutine_info *info = get_coroutine_info (decl))
633    return info->promise_proxy;
634
635  return NULL_TREE;
636}
637
638static tree
639lookup_promise_method (tree fndecl, tree member_id, location_t loc,
640		       bool musthave)
641{
642  tree promise = get_coroutine_promise_type (fndecl);
643  tree pm_memb
644    = lookup_member (promise, member_id,
645		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
646  if (musthave && pm_memb == NULL_TREE)
647    {
648      error_at (loc, "no member named %qE in %qT", member_id, promise);
649      return error_mark_node;
650    }
651  return pm_memb;
652}
653
654/* Build an expression of the form p.method (args) where the p is a promise
655   object for the current coroutine.
656   OBJECT is the promise object instance to use, it may be NULL, in which case
657   we will use the promise_proxy instance for this coroutine.
658   ARGS may be NULL, for empty parm lists.  */
659
660static tree
661coro_build_promise_expression (tree fn, tree promise_obj, tree member_id,
662			       location_t loc, vec<tree, va_gc> **args,
663			       bool musthave)
664{
665  tree meth = lookup_promise_method (fn, member_id, loc, musthave);
666  if (meth == error_mark_node)
667    return error_mark_node;
668
669  /* If we don't find it, and it isn't needed, an empty return is OK.  */
670  if (!meth)
671    return NULL_TREE;
672
673  tree promise
674    = promise_obj ? promise_obj
675		  : get_coroutine_promise_proxy (current_function_decl);
676  tree expr;
677  if (BASELINK_P (meth))
678    expr = build_new_method_call (promise, meth, args, NULL_TREE,
679				  LOOKUP_NORMAL, NULL, tf_warning_or_error);
680  else
681    {
682      expr = build_class_member_access_expr (promise, meth, NULL_TREE,
683					     true, tf_warning_or_error);
684      vec<tree, va_gc> *real_args;
685      if (!args)
686	real_args = make_tree_vector ();
687      else
688	real_args = *args;
689      expr = build_op_call (expr, &real_args, tf_warning_or_error);
690    }
691  return expr;
692}
693
694/* Caching get for the expression p.return_void ().  */
695
696static tree
697get_coroutine_return_void_expr (tree decl, location_t loc, bool musthave)
698{
699  if (coroutine_info *info = get_coroutine_info (decl))
700    {
701      /* If we don't have it try to build it.  */
702      if (!info->return_void)
703	info->return_void
704	  = coro_build_promise_expression (current_function_decl, NULL,
705					   coro_return_void_identifier,
706					   loc, NULL, musthave);
707      /* Don't return an error if it's an optional call.  */
708      if (!musthave && info->return_void == error_mark_node)
709	return NULL_TREE;
710      return info->return_void;
711    }
712  return musthave ? error_mark_node : NULL_TREE;
713}
714
715/* Lookup an Awaitable member, which should be await_ready, await_suspend
716   or await_resume.  */
717
718static tree
719lookup_awaitable_member (tree await_type, tree member_id, location_t loc)
720{
721  tree aw_memb
722    = lookup_member (await_type, member_id,
723		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
724  if (aw_memb == NULL_TREE)
725    {
726      error_at (loc, "no member named %qE in %qT", member_id, await_type);
727      return error_mark_node;
728    }
729  return aw_memb;
730}
731
732/* Here we check the constraints that are common to all keywords (since the
733   presence of a coroutine keyword makes the function into a coroutine).  */
734
735static bool
736coro_common_keyword_context_valid_p (tree fndecl, location_t kw_loc,
737				     const char *kw_name)
738{
739  if (fndecl == NULL_TREE)
740    {
741      error_at (kw_loc, "%qs cannot be used outside a function", kw_name);
742      return false;
743    }
744
745  /* This is arranged in order of prohibitions in the std.  */
746  if (DECL_MAIN_P (fndecl))
747    {
748      /* [basic.start.main] 3. The function main shall not be a coroutine.  */
749      error_at (kw_loc, "%qs cannot be used in the %<main%> function",
750		kw_name);
751      return false;
752    }
753
754  if (DECL_DECLARED_CONSTEXPR_P (fndecl))
755    {
756      cp_function_chain->invalid_constexpr = true;
757      if (!is_instantiation_of_constexpr (fndecl))
758	{
759	  /* [dcl.constexpr] 3.3 it shall not be a coroutine.  */
760	  error_at (kw_loc, "%qs cannot be used in a %<constexpr%> function",
761		    kw_name);
762	  return false;
763	}
764    }
765
766  if (FNDECL_USED_AUTO (fndecl))
767    {
768      /* [dcl.spec.auto] 15. A function declared with a return type that uses
769	 a placeholder type shall not be a coroutine.  */
770      error_at (kw_loc,
771		"%qs cannot be used in a function with a deduced return type",
772		kw_name);
773      return false;
774    }
775
776  if (varargs_function_p (fndecl))
777    {
778      /* [dcl.fct.def.coroutine] The parameter-declaration-clause of the
779	 coroutine shall not terminate with an ellipsis that is not part
780	 of a parameter-declaration.  */
781      error_at (kw_loc,
782		"%qs cannot be used in a varargs function", kw_name);
783      return false;
784    }
785
786  if (DECL_CONSTRUCTOR_P (fndecl))
787    {
788      /* [class.ctor] 7. a constructor shall not be a coroutine.  */
789      error_at (kw_loc, "%qs cannot be used in a constructor", kw_name);
790      return false;
791    }
792
793  if (DECL_DESTRUCTOR_P (fndecl))
794    {
795      /* [class.dtor] 21. a destructor shall not be a coroutine.  */
796      error_at (kw_loc, "%qs cannot be used in a destructor", kw_name);
797      return false;
798    }
799
800  return true;
801}
802
803/* Here we check the constraints that are not per keyword.  */
804
805static bool
806coro_function_valid_p (tree fndecl)
807{
808  location_t f_loc = DECL_SOURCE_LOCATION (fndecl);
809
810  /* For cases where fundamental information cannot be found, e.g. the
811     coroutine traits are missing, we need to punt early.  */
812  if (!coro_promise_type_found_p (fndecl, f_loc))
813    return false;
814
815  /* Since we think the function is a coroutine, that implies we parsed
816     a keyword that triggered this.  Keywords check promise validity for
817     their context and thus the promise type should be known at this point.  */
818  if (get_coroutine_handle_type (fndecl) == NULL_TREE
819      || get_coroutine_promise_type (fndecl) == NULL_TREE)
820    return false;
821
822  if (current_function_returns_value || current_function_returns_null)
823    {
824       /* TODO: record or extract positions of returns (and the first coro
825	  keyword) so that we can add notes to the diagnostic about where
826	  the bad keyword is and what made the function into a coro.  */
827      error_at (f_loc, "a %<return%> statement is not allowed in coroutine;"
828			" did you mean %<co_return%>?");
829      return false;
830    }
831
832  return true;
833}
834
835enum suspend_point_kind {
836  CO_AWAIT_SUSPEND_POINT = 0,
837  CO_YIELD_SUSPEND_POINT,
838  INITIAL_SUSPEND_POINT,
839  FINAL_SUSPEND_POINT
840};
841
842/* Helper function to build a named variable for the temps we use for each
843   await point.  The root of the name is determined by SUSPEND_KIND, and
844   the variable is of type V_TYPE.  The awaitable number is reset each time
845   we encounter a final suspend.  */
846
847static tree
848get_awaitable_var (suspend_point_kind suspend_kind, tree v_type)
849{
850  static int awn = 0;
851  char *buf;
852  switch (suspend_kind)
853    {
854      default: buf = xasprintf ("Aw%d", awn++); break;
855      case CO_YIELD_SUSPEND_POINT: buf =  xasprintf ("Yd%d", awn++); break;
856      case INITIAL_SUSPEND_POINT: buf =  xasprintf ("Is"); break;
857      case FINAL_SUSPEND_POINT: buf =  xasprintf ("Fs"); awn = 0; break;
858  }
859  tree ret = get_identifier (buf);
860  free (buf);
861  ret = build_lang_decl (VAR_DECL, ret, v_type);
862  DECL_ARTIFICIAL (ret) = true;
863  return ret;
864}
865
866/* Helpers to diagnose missing noexcept on final await expressions.  */
867
868static bool
869coro_diagnose_throwing_fn (tree fndecl)
870{
871  if (!TYPE_NOTHROW_P (TREE_TYPE (fndecl)))
872    {
873      location_t f_loc = cp_expr_loc_or_loc (fndecl,
874					     DECL_SOURCE_LOCATION (fndecl));
875      error_at (f_loc, "the expression %qE is required to be non-throwing",
876		fndecl);
877      inform (f_loc, "must be declared with %<noexcept(true)%>");
878      return true;
879    }
880  return false;
881}
882
883static bool
884coro_diagnose_throwing_final_aw_expr (tree expr)
885{
886  if (TREE_CODE (expr) == TARGET_EXPR)
887    expr = TARGET_EXPR_INITIAL (expr);
888  tree fn = NULL_TREE;
889  if (TREE_CODE (expr) == CALL_EXPR)
890    fn = CALL_EXPR_FN (expr);
891  else if (TREE_CODE (expr) == AGGR_INIT_EXPR)
892    fn = AGGR_INIT_EXPR_FN (expr);
893  else if (TREE_CODE (expr) == CONSTRUCTOR)
894    return false;
895  else
896    {
897      gcc_checking_assert (0 && "unhandled expression type");
898      return false;
899    }
900  fn = TREE_OPERAND (fn, 0);
901  return coro_diagnose_throwing_fn (fn);
902}
903
904/*  This performs [expr.await] bullet 3.3 and validates the interface obtained.
905    It is also used to build the initial and final suspend points.
906
907    'a', 'o' and 'e' are used as per the description in the section noted.
908
909    A, the original yield/await expr, is found at source location LOC.
910
911    We will be constructing a CO_AWAIT_EXPR for a suspend point of one of
912    the four suspend_point_kind kinds.  This is indicated by SUSPEND_KIND.  */
913
914static tree
915build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind)
916{
917  /* Try and overload of operator co_await, .... */
918  tree o;
919  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (a)))
920    {
921      o = build_new_op (loc, CO_AWAIT_EXPR, LOOKUP_NORMAL, a, NULL_TREE,
922			NULL_TREE, NULL_TREE, NULL, tf_warning_or_error);
923      /* If no viable functions are found, o is a.  */
924      if (!o || o == error_mark_node)
925	o = a;
926      else if (flag_exceptions && suspend_kind == FINAL_SUSPEND_POINT)
927	{
928	  /* We found an overload for co_await(), diagnose throwing cases.  */
929	  if (TREE_CODE (o) == TARGET_EXPR
930	      && coro_diagnose_throwing_final_aw_expr (o))
931	    return error_mark_node;
932
933	  /* We now know that the final suspend object is distinct from the
934	     final awaiter, so check for a non-throwing DTOR where needed.  */
935	  tree a_type = TREE_TYPE (a);
936	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (a_type))
937	    if (tree dummy
938		= build_special_member_call (a, complete_dtor_identifier,
939					     NULL, a_type, LOOKUP_NORMAL,
940					     tf_none))
941	      {
942		if (CONVERT_EXPR_P (dummy))
943		  dummy = TREE_OPERAND (dummy, 0);
944		dummy = TREE_OPERAND (CALL_EXPR_FN (dummy), 0);
945		if (coro_diagnose_throwing_fn (dummy))
946		  return error_mark_node;
947	      }
948	}
949    }
950  else
951    o = a; /* This is most likely about to fail anyway.  */
952
953  tree o_type = TREE_TYPE (o);
954  if (o_type && !VOID_TYPE_P (o_type))
955    o_type = complete_type_or_else (o_type, o);
956
957  if (!o_type)
958    return error_mark_node;
959
960  if (TREE_CODE (o_type) != RECORD_TYPE)
961    {
962      error_at (loc, "awaitable type %qT is not a structure",
963		o_type);
964      return error_mark_node;
965    }
966
967  /* Check for required awaitable members and their types.  */
968  tree awrd_meth
969    = lookup_awaitable_member (o_type, coro_await_ready_identifier, loc);
970  if (!awrd_meth || awrd_meth == error_mark_node)
971    return error_mark_node;
972  tree awsp_meth
973    = lookup_awaitable_member (o_type, coro_await_suspend_identifier, loc);
974  if (!awsp_meth || awsp_meth == error_mark_node)
975    return error_mark_node;
976
977  /* The type of the co_await is the return type of the awaitable's
978     await_resume, so we need to look that up.  */
979  tree awrs_meth
980    = lookup_awaitable_member (o_type, coro_await_resume_identifier, loc);
981  if (!awrs_meth || awrs_meth == error_mark_node)
982    return error_mark_node;
983
984  /* To complete the lookups, we need an instance of 'e' which is built from
985     'o' according to [expr.await] 3.4.
986
987     If we need to materialize this as a temporary, then that will have to be
988     'promoted' to a coroutine frame var.  However, if the awaitable is a
989     user variable, parameter or comes from a scope outside this function,
990     then we must use it directly - or we will see unnecessary copies.
991
992     If o is a variable, find the underlying var.  */
993  tree e_proxy = STRIP_NOPS (o);
994  if (INDIRECT_REF_P (e_proxy))
995    e_proxy = TREE_OPERAND (e_proxy, 0);
996  while (TREE_CODE (e_proxy) == COMPONENT_REF)
997    {
998      e_proxy = TREE_OPERAND (e_proxy, 0);
999      if (INDIRECT_REF_P (e_proxy))
1000	e_proxy = TREE_OPERAND (e_proxy, 0);
1001      if (TREE_CODE (e_proxy) == CALL_EXPR)
1002	{
1003	  /* We could have operator-> here too.  */
1004	  tree op = TREE_OPERAND (CALL_EXPR_FN (e_proxy), 0);
1005	  if (DECL_OVERLOADED_OPERATOR_P (op)
1006	      && DECL_OVERLOADED_OPERATOR_IS (op, COMPONENT_REF))
1007	    {
1008	      e_proxy = CALL_EXPR_ARG (e_proxy, 0);
1009	      STRIP_NOPS (e_proxy);
1010	      gcc_checking_assert (TREE_CODE (e_proxy) == ADDR_EXPR);
1011	      e_proxy = TREE_OPERAND (e_proxy, 0);
1012	    }
1013	}
1014      STRIP_NOPS (e_proxy);
1015    }
1016
1017  /* Only build a temporary if we need it.  */
1018  STRIP_NOPS (e_proxy);
1019  if (TREE_CODE (e_proxy) == PARM_DECL
1020      || (VAR_P (e_proxy) && !is_local_temp (e_proxy)))
1021    {
1022      e_proxy = o;
1023      o = NULL_TREE; /* The var is already present.  */
1024    }
1025  else
1026    {
1027      tree p_type = o_type;
1028      if (glvalue_p (o))
1029	p_type = cp_build_reference_type (p_type, !lvalue_p (o));
1030      e_proxy = get_awaitable_var (suspend_kind, p_type);
1031      o = cp_build_modify_expr (loc, e_proxy, INIT_EXPR, o,
1032				tf_warning_or_error);
1033      e_proxy = convert_from_reference (e_proxy);
1034    }
1035
1036  /* I suppose we could check that this is contextually convertible to bool.  */
1037  tree awrd_func = NULL_TREE;
1038  tree awrd_call
1039    = build_new_method_call (e_proxy, awrd_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
1040			     &awrd_func, tf_warning_or_error);
1041
1042  if (!awrd_func || !awrd_call || awrd_call == error_mark_node)
1043    return error_mark_node;
1044
1045  /* The suspend method may return one of three types:
1046      1. void (no special action needed).
1047      2. bool (if true, we don't need to suspend).
1048      3. a coroutine handle, we execute the handle.resume() call.  */
1049  tree awsp_func = NULL_TREE;
1050  tree h_proxy = get_coroutine_self_handle_proxy (current_function_decl);
1051  vec<tree, va_gc> *args = make_tree_vector_single (h_proxy);
1052  tree awsp_call
1053    = build_new_method_call (e_proxy, awsp_meth, &args, NULL_TREE,
1054			     LOOKUP_NORMAL, &awsp_func, tf_warning_or_error);
1055
1056  release_tree_vector (args);
1057  if (!awsp_func || !awsp_call || awsp_call == error_mark_node)
1058    return error_mark_node;
1059
1060  bool ok = false;
1061  tree susp_return_type = TREE_TYPE (TREE_TYPE (awsp_func));
1062  if (same_type_p (susp_return_type, void_type_node))
1063    ok = true;
1064  else if (same_type_p (susp_return_type, boolean_type_node))
1065    ok = true;
1066  else if (TREE_CODE (susp_return_type) == RECORD_TYPE
1067	   && CLASS_TYPE_P (susp_return_type)
1068	   && CLASSTYPE_TEMPLATE_INFO (susp_return_type))
1069    {
1070      tree tt = CLASSTYPE_TI_TEMPLATE (susp_return_type);
1071      if (tt == coro_handle_templ)
1072	ok = true;
1073    }
1074
1075  if (!ok)
1076    {
1077      error_at (loc, "%<await_suspend%> must return %<void%>, %<bool%> or"
1078		     " a coroutine handle");
1079      return error_mark_node;
1080    }
1081
1082  /* Finally, the type of e.await_resume() is the co_await's type.  */
1083  tree awrs_func = NULL_TREE;
1084  tree awrs_call
1085    = build_new_method_call (e_proxy, awrs_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
1086			     &awrs_func, tf_warning_or_error);
1087
1088  if (!awrs_func || !awrs_call || awrs_call == error_mark_node)
1089    return error_mark_node;
1090
1091  if (flag_exceptions && suspend_kind == FINAL_SUSPEND_POINT)
1092    {
1093      if (coro_diagnose_throwing_fn (awrd_func))
1094	return error_mark_node;
1095      if (coro_diagnose_throwing_fn (awsp_func))
1096	return error_mark_node;
1097      if (coro_diagnose_throwing_fn (awrs_func))
1098	return error_mark_node;
1099      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (o_type))
1100	if (tree dummy
1101	    = build_special_member_call (e_proxy, complete_dtor_identifier,
1102					 NULL, o_type, LOOKUP_NORMAL,
1103					 tf_none))
1104	  {
1105	    if (CONVERT_EXPR_P (dummy))
1106	      dummy = TREE_OPERAND (dummy, 0);
1107	    dummy = TREE_OPERAND (CALL_EXPR_FN (dummy), 0);
1108	    if (coro_diagnose_throwing_fn (dummy))
1109	      return error_mark_node;
1110	  }
1111    }
1112
1113  /* We now have three call expressions, in terms of the promise, handle and
1114     'e' proxies.  Save them in the await expression for later expansion.  */
1115
1116  tree awaiter_calls = make_tree_vec (3);
1117  TREE_VEC_ELT (awaiter_calls, 0) = awrd_call; /* await_ready().  */
1118  TREE_VEC_ELT (awaiter_calls, 1) = awsp_call; /* await_suspend().  */
1119  tree te = NULL_TREE;
1120  if (TREE_CODE (awrs_call) == TARGET_EXPR)
1121    {
1122      te = awrs_call;
1123      awrs_call = TREE_OPERAND (awrs_call, 1);
1124    }
1125  TREE_VEC_ELT (awaiter_calls, 2) = awrs_call; /* await_resume().  */
1126
1127  if (REFERENCE_REF_P (e_proxy))
1128    e_proxy = TREE_OPERAND (e_proxy, 0);
1129
1130  tree await_expr = build5_loc (loc, CO_AWAIT_EXPR,
1131				TREE_TYPE (TREE_TYPE (awrs_func)),
1132				a, e_proxy, o, awaiter_calls,
1133				build_int_cst (integer_type_node,
1134					       (int) suspend_kind));
1135  TREE_SIDE_EFFECTS (await_expr) = true;
1136  if (te)
1137    {
1138      TREE_OPERAND (te, 1) = await_expr;
1139      TREE_SIDE_EFFECTS (te) = true;
1140      await_expr = te;
1141    }
1142  SET_EXPR_LOCATION (await_expr, loc);
1143  return convert_from_reference (await_expr);
1144}
1145
1146tree
1147finish_co_await_expr (location_t kw, tree expr)
1148{
1149  if (!expr || error_operand_p (expr))
1150    return error_mark_node;
1151
1152  if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
1153					    "co_await"))
1154    return error_mark_node;
1155
1156  /* The current function has now become a coroutine, if it wasn't already.  */
1157  DECL_COROUTINE_P (current_function_decl) = 1;
1158
1159  /* This function will appear to have no return statement, even if it
1160     is declared to return non-void (most likely).  This is correct - we
1161     synthesize the return for the ramp in the compiler.  So suppress any
1162     extraneous warnings during substitution.  */
1163  suppress_warning (current_function_decl, OPT_Wreturn_type);
1164
1165  /* Defer expansion when we are processing a template.
1166     FIXME: If the coroutine function's type is not dependent, and the operand
1167     is not dependent, we should determine the type of the co_await expression
1168     using the DEPENDENT_EXPR wrapper machinery.  That allows us to determine
1169     the subexpression type, but leave its operand unchanged and then
1170     instantiate it later.  */
1171  if (processing_template_decl)
1172    {
1173      tree aw_expr = build5_loc (kw, CO_AWAIT_EXPR, unknown_type_node, expr,
1174				 NULL_TREE, NULL_TREE, NULL_TREE,
1175				 integer_zero_node);
1176      TREE_SIDE_EFFECTS (aw_expr) = true;
1177      return aw_expr;
1178    }
1179
1180  /* We must be able to look up the "await_transform" method in the scope of
1181     the promise type, and obtain its return type.  */
1182  if (!coro_promise_type_found_p (current_function_decl, kw))
1183    return error_mark_node;
1184
1185  /* [expr.await] 3.2
1186     The incoming cast expression might be transformed by a promise
1187     'await_transform()'.  */
1188  tree at_meth
1189    = lookup_promise_method (current_function_decl,
1190			     coro_await_transform_identifier, kw,
1191			     /*musthave=*/false);
1192  if (at_meth == error_mark_node)
1193    return error_mark_node;
1194
1195  tree a = expr;
1196  if (at_meth)
1197    {
1198      /* try to build a = p.await_transform (e). */
1199      vec<tree, va_gc> *args = make_tree_vector_single (expr);
1200      a = build_new_method_call (get_coroutine_promise_proxy (
1201				   current_function_decl),
1202				 at_meth, &args, NULL_TREE, LOOKUP_NORMAL,
1203				 NULL, tf_warning_or_error);
1204
1205      /* As I read the section.
1206	 We saw an await_transform method, so it's mandatory that we replace
1207	 expr with p.await_transform (expr), therefore if the method call fails
1208	 (presumably, we don't have suitable arguments) then this part of the
1209	 process fails.  */
1210      if (a == error_mark_node)
1211	return error_mark_node;
1212    }
1213
1214  /* Now we want to build co_await a.  */
1215  return build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT);
1216}
1217
1218/* Take the EXPR given and attempt to build:
1219     co_await p.yield_value (expr);
1220   per [expr.yield] para 1. */
1221
1222tree
1223finish_co_yield_expr (location_t kw, tree expr)
1224{
1225  if (!expr || error_operand_p (expr))
1226    return error_mark_node;
1227
1228  /* Check the general requirements and simple syntax errors.  */
1229  if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
1230					    "co_yield"))
1231    return error_mark_node;
1232
1233  /* The current function has now become a coroutine, if it wasn't already.  */
1234  DECL_COROUTINE_P (current_function_decl) = 1;
1235
1236  /* This function will appear to have no return statement, even if it
1237     is declared to return non-void (most likely).  This is correct - we
1238     synthesize the return for the ramp in the compiler.  So suppress any
1239     extraneous warnings during substitution.  */
1240  suppress_warning (current_function_decl, OPT_Wreturn_type);
1241
1242  /* Defer expansion when we are processing a template; see FIXME in the
1243     co_await code.  */
1244  if (processing_template_decl)
1245    return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr, NULL_TREE);
1246
1247  if (!coro_promise_type_found_p (current_function_decl, kw))
1248    /* We must be able to look up the "yield_value" method in the scope of
1249       the promise type, and obtain its return type.  */
1250    return error_mark_node;
1251
1252  /* [expr.yield] / 1
1253     Let e be the operand of the yield-expression and p be an lvalue naming
1254     the promise object of the enclosing coroutine, then the yield-expression
1255     is equivalent to the expression co_await p.yield_value(e).
1256     build p.yield_value(e):  */
1257  vec<tree, va_gc> *args = make_tree_vector_single (expr);
1258  tree yield_call
1259    = coro_build_promise_expression (current_function_decl, NULL,
1260				     coro_yield_value_identifier, kw,
1261				     &args, /*musthave=*/true);
1262  release_tree_vector (args);
1263
1264  /* Now build co_await p.yield_value (e).
1265     Noting that for co_yield, there is no evaluation of any potential
1266     promise transform_await(), so we call build_co_await directly.  */
1267
1268  tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
1269  if (op != error_mark_node)
1270    {
1271      if (REFERENCE_REF_P (op))
1272	op = TREE_OPERAND (op, 0);
1273      /* If the await expression is wrapped in a TARGET_EXPR, then transfer
1274	 that wrapper to the CO_YIELD_EXPR, since this is just a proxy for
1275	 its contained await.  Otherwise, just build the CO_YIELD_EXPR.  */
1276      if (TREE_CODE (op) == TARGET_EXPR)
1277	{
1278	  tree t = TREE_OPERAND (op, 1);
1279	  t = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (t), expr, t);
1280	  TREE_OPERAND (op, 1) = t;
1281	}
1282      else
1283	op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
1284      TREE_SIDE_EFFECTS (op) = 1;
1285      op = convert_from_reference (op);
1286    }
1287
1288  return op;
1289}
1290
1291/* Check and build a co_return statement.
1292   First that it's valid to have a co_return keyword here.
1293   If it is, then check and build the p.return_{void(),value(expr)}.
1294   These are built against a proxy for the promise, which will be filled
1295   in with the actual frame version when the function is transformed.  */
1296
1297tree
1298finish_co_return_stmt (location_t kw, tree expr)
1299{
1300  if (expr)
1301    STRIP_ANY_LOCATION_WRAPPER (expr);
1302
1303  if (error_operand_p (expr))
1304    return error_mark_node;
1305
1306  /* If it fails the following test, the function is not permitted to be a
1307     coroutine, so the co_return statement is erroneous.  */
1308  if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
1309					    "co_return"))
1310    return error_mark_node;
1311
1312  /* The current function has now become a coroutine, if it wasn't
1313     already.  */
1314  DECL_COROUTINE_P (current_function_decl) = 1;
1315
1316  /* This function will appear to have no return statement, even if it
1317     is declared to return non-void (most likely).  This is correct - we
1318     synthesize the return for the ramp in the compiler.  So suppress any
1319     extraneous warnings during substitution.  */
1320  suppress_warning (current_function_decl, OPT_Wreturn_type);
1321
1322  if (processing_template_decl
1323      && check_for_bare_parameter_packs (expr))
1324    return error_mark_node;
1325
1326  /* Defer expansion when we are processing a template; see FIXME in the
1327     co_await code.  */
1328  if (processing_template_decl)
1329    {
1330      /* co_return expressions are always void type, regardless of the
1331	 expression type.  */
1332      expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node,
1333			 expr, NULL_TREE);
1334      expr = maybe_cleanup_point_expr_void (expr);
1335      return add_stmt (expr);
1336    }
1337
1338  if (!coro_promise_type_found_p (current_function_decl, kw))
1339    return error_mark_node;
1340
1341  /* Suppress -Wreturn-type for co_return, we need to check indirectly
1342     whether the promise type has a suitable return_void/return_value.  */
1343  suppress_warning (current_function_decl, OPT_Wreturn_type);
1344
1345  if (!processing_template_decl && warn_sequence_point)
1346    verify_sequence_points (expr);
1347
1348  if (expr)
1349    {
1350      /* If we had an id-expression obfuscated by force_paren_expr, we need
1351	 to undo it so we can try to treat it as an rvalue below.  */
1352      expr = maybe_undo_parenthesized_ref (expr);
1353
1354      if (processing_template_decl)
1355	expr = build_non_dependent_expr (expr);
1356
1357      if (error_operand_p (expr))
1358	return error_mark_node;
1359    }
1360
1361  /* If the promise object doesn't have the correct return call then
1362     there's a mis-match between the co_return <expr> and this.  */
1363  tree co_ret_call = error_mark_node;
1364  if (expr == NULL_TREE || VOID_TYPE_P (TREE_TYPE (expr)))
1365    co_ret_call
1366      = get_coroutine_return_void_expr (current_function_decl, kw, true);
1367  else
1368    {
1369      /* [class.copy.elision] / 3.
1370	 An implicitly movable entity is a variable of automatic storage
1371	 duration that is either a non-volatile object or an rvalue reference
1372	 to a non-volatile object type.  For such objects in the context of
1373	 the co_return, the overload resolution should be carried out first
1374	 treating the object as an rvalue, if that fails, then we fall back
1375	 to regular overload resolution.  */
1376
1377      tree arg = expr;
1378      if (tree moved = treat_lvalue_as_rvalue_p (expr, /*return*/true))
1379	arg = moved;
1380
1381      releasing_vec args = make_tree_vector_single (arg);
1382      co_ret_call
1383	= coro_build_promise_expression (current_function_decl, NULL,
1384					 coro_return_value_identifier, kw,
1385					 &args, /*musthave=*/true);
1386    }
1387
1388  /* Makes no sense for a co-routine really. */
1389  if (TREE_THIS_VOLATILE (current_function_decl))
1390    warning_at (kw, 0,
1391		"function declared %<noreturn%> has a"
1392		" %<co_return%> statement");
1393
1394  expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node, expr, co_ret_call);
1395  expr = maybe_cleanup_point_expr_void (expr);
1396  return add_stmt (expr);
1397}
1398
1399/* We need to validate the arguments to __builtin_coro_promise, since the
1400   second two must be constant, and the builtins machinery doesn't seem to
1401   deal with that properly.  */
1402
1403tree
1404coro_validate_builtin_call (tree call, tsubst_flags_t)
1405{
1406  tree fn = TREE_OPERAND (CALL_EXPR_FN (call), 0);
1407
1408  gcc_checking_assert (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL);
1409  switch (DECL_FUNCTION_CODE (fn))
1410    {
1411    default:
1412      return call;
1413
1414    case BUILT_IN_CORO_PROMISE:
1415      {
1416	/* Argument 0 is already checked by the normal built-in machinery
1417	   Argument 1 must be a constant of size type.  It probably makes
1418	   little sense if it's not a power of 2, but that isn't specified
1419	   formally.  */
1420	tree arg = CALL_EXPR_ARG (call, 1);
1421	location_t loc = EXPR_LOCATION (arg);
1422
1423	/* We expect alignof expressions in templates.  */
1424	if (TREE_CODE (arg) == NON_DEPENDENT_EXPR
1425	    && TREE_CODE (TREE_OPERAND (arg, 0)) == ALIGNOF_EXPR)
1426	  ;
1427	else if (!TREE_CONSTANT (arg))
1428	  {
1429	    error_at (loc, "the align argument to %<__builtin_coro_promise%>"
1430			   " must be a constant");
1431	    return error_mark_node;
1432	  }
1433	/* Argument 2 is the direction - to / from handle address to promise
1434	   address.  */
1435	arg = CALL_EXPR_ARG (call, 2);
1436	loc = EXPR_LOCATION (arg);
1437	if (!TREE_CONSTANT (arg))
1438	  {
1439	    error_at (loc, "the direction argument to"
1440			   " %<__builtin_coro_promise%> must be a constant");
1441	    return error_mark_node;
1442	  }
1443	return call;
1444	break;
1445      }
1446    }
1447}
1448
1449/* ================= Morph and Expand. =================
1450
1451   The entry point here is morph_fn_to_coro () which is called from
1452   finish_function () when we have completed any template expansion.
1453
1454   This is preceded by helper functions that implement the phases below.
1455
1456   The process proceeds in four phases.
1457
1458   A Initial framing.
1459     The user's function body is wrapped in the initial and final suspend
1460     points and we begin building the coroutine frame.
1461     We build empty decls for the actor and destroyer functions at this
1462     time too.
1463     When exceptions are enabled, the user's function body will also be
1464     wrapped in a try-catch block with the catch invoking the promise
1465     class 'unhandled_exception' method.
1466
1467   B Analysis.
1468     The user's function body is analyzed to determine the suspend points,
1469     if any, and to capture local variables that might persist across such
1470     suspensions.  In most cases, it is not necessary to capture compiler
1471     temporaries, since the tree-lowering nests the suspensions correctly.
1472     However, in the case of a captured reference, there is a lifetime
1473     extension to the end of the full expression - which can mean across a
1474     suspend point in which case it must be promoted to a frame variable.
1475
1476     At the conclusion of analysis, we have a conservative frame layout and
1477     maps of the local variables to their frame entry points.
1478
1479   C Build the ramp function.
1480     Carry out the allocation for the coroutine frame (NOTE; the actual size
1481     computation is deferred until late in the middle end to allow for future
1482     optimizations that will be allowed to elide unused frame entries).
1483     We build the return object.
1484
1485   D Build and expand the actor and destroyer function bodies.
1486     The destroyer is a trivial shim that sets a bit to indicate that the
1487     destroy dispatcher should be used and then calls into the actor.
1488
1489     The actor function is the implementation of the user's state machine.
1490     The current suspend point is noted in an index.
1491     Each suspend point is encoded as a pair of internal functions, one in
1492     the relevant dispatcher, and one representing the suspend point.
1493
1494     During this process, the user's local variables and the proxies for the
1495     self-handle and the promise class instance are re-written to their
1496     coroutine frame equivalents.
1497
1498     The complete bodies for the ramp, actor and destroy function are passed
1499     back to finish_function for folding and gimplification.  */
1500
1501/* Helpers to build EXPR_STMT and void-cast EXPR_STMT, common ops.  */
1502
1503static tree
1504coro_build_expr_stmt (tree expr, location_t loc)
1505{
1506  return maybe_cleanup_point_expr_void (build_stmt (loc, EXPR_STMT, expr));
1507}
1508
1509static tree
1510coro_build_cvt_void_expr_stmt (tree expr, location_t loc)
1511{
1512  tree t = build1 (CONVERT_EXPR, void_type_node, expr);
1513  return coro_build_expr_stmt (t, loc);
1514}
1515
1516/* Helpers to build an artificial var, with location LOC, NAME and TYPE, in
1517   CTX, and with initializer INIT.  */
1518
1519static tree
1520coro_build_artificial_var (location_t loc, tree name, tree type, tree ctx,
1521			   tree init)
1522{
1523  tree res = build_lang_decl (VAR_DECL, name, type);
1524  DECL_SOURCE_LOCATION (res) = loc;
1525  DECL_CONTEXT (res) = ctx;
1526  DECL_ARTIFICIAL (res) = true;
1527  DECL_INITIAL (res) = init;
1528  return res;
1529}
1530
1531static tree
1532coro_build_artificial_var (location_t loc, const char *name, tree type,
1533			   tree ctx, tree init)
1534{
1535  return coro_build_artificial_var (loc, get_identifier (name),
1536				    type, ctx, init);
1537}
1538
1539/* Helpers for label creation:
1540   1. Create a named label in the specified context.  */
1541
1542static tree
1543create_anon_label_with_ctx (location_t loc, tree ctx)
1544{
1545  tree lab = build_decl (loc, LABEL_DECL, NULL_TREE, void_type_node);
1546
1547  DECL_CONTEXT (lab) = ctx;
1548  DECL_ARTIFICIAL (lab) = true;
1549  DECL_IGNORED_P (lab) = true;
1550  TREE_USED (lab) = true;
1551  return lab;
1552}
1553
1554/*  2. Create a named label in the specified context.  */
1555
1556static tree
1557create_named_label_with_ctx (location_t loc, const char *name, tree ctx)
1558{
1559  tree lab_id = get_identifier (name);
1560  tree lab = define_label (loc, lab_id);
1561  DECL_CONTEXT (lab) = ctx;
1562  DECL_ARTIFICIAL (lab) = true;
1563  TREE_USED (lab) = true;
1564  return lab;
1565}
1566
1567struct proxy_replace
1568{
1569  tree from, to;
1570};
1571
1572static tree
1573replace_proxy (tree *here, int *do_subtree, void *d)
1574{
1575  proxy_replace *data = (proxy_replace *) d;
1576
1577  if (*here == data->from)
1578    {
1579      *here = data->to;
1580      *do_subtree = 0;
1581    }
1582  else
1583    *do_subtree = 1;
1584  return NULL_TREE;
1585}
1586
1587/* Support for expansion of co_await statements.  */
1588
1589struct coro_aw_data
1590{
1591  tree actor_fn;   /* Decl for context.  */
1592  tree coro_fp;    /* Frame pointer var.  */
1593  tree resume_idx; /* This is the index var in the frame.  */
1594  tree i_a_r_c;    /* initial suspend await_resume() was called if true.  */
1595  tree self_h;     /* This is a handle to the current coro (frame var).  */
1596  tree cleanup;    /* This is where to go once we complete local destroy.  */
1597  tree cororet;    /* This is where to go if we suspend.  */
1598  tree corocont;   /* This is where to go if we continue.  */
1599  tree conthand;   /* This is the handle for a continuation.  */
1600  unsigned index;  /* This is our current resume index.  */
1601};
1602
1603/* Lightweight search for the first await expression in tree-walk order.
1604   returns:
1605     The first await expression found in STMT.
1606     NULL_TREE if there are none.
1607   So can be used to determine if the statement needs to be processed for
1608   awaits.  */
1609
1610static tree
1611co_await_find_in_subtree (tree *stmt, int *, void *d)
1612{
1613  tree **p = (tree **) d;
1614  if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
1615    {
1616      *p = stmt;
1617      return *stmt;
1618    }
1619  return NULL_TREE;
1620}
1621
1622/* Starting with a statement:
1623
1624   stmt => some tree containing one or more await expressions.
1625
1626   We replace the statement with:
1627   <STATEMENT_LIST> {
1628      initialize awaitable
1629      if (!ready)
1630	{
1631	  suspension context.
1632	}
1633      resume:
1634	revised statement with one await expression rewritten to its
1635	await_resume() return value.
1636   }
1637
1638   We then recurse into the initializer and the revised statement
1639   repeating this replacement until there are no more await expressions
1640   in either.  */
1641
1642static tree *
1643expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
1644{
1645  coro_aw_data *data = (coro_aw_data *) d;
1646
1647  tree saved_statement = *stmt;
1648  tree saved_co_await = *await_expr;
1649
1650  tree actor = data->actor_fn;
1651  location_t loc = EXPR_LOCATION (*stmt);
1652  tree var = TREE_OPERAND (saved_co_await, 1);  /* frame slot. */
1653  tree expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
1654  tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);
1655
1656  tree source = TREE_OPERAND (saved_co_await, 4);
1657  bool is_final = (source
1658		   && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
1659  bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
1660  int resume_point = data->index;
1661  size_t bufsize = sizeof ("destroy.") + 10;
1662  char *buf = (char *) alloca (bufsize);
1663  snprintf (buf, bufsize, "destroy.%d", resume_point);
1664  tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
1665  snprintf (buf, bufsize, "resume.%d", resume_point);
1666  tree resume_label = create_named_label_with_ctx (loc, buf, actor);
1667  tree empty_list = build_empty_stmt (loc);
1668
1669  tree await_type = TREE_TYPE (var);
1670  tree stmt_list = NULL;
1671  tree r;
1672  tree *await_init = NULL;
1673
1674  if (!expr)
1675    needs_dtor = false; /* No need, the var's lifetime is managed elsewhere.  */
1676  else
1677    {
1678      r = coro_build_cvt_void_expr_stmt (expr, loc);
1679      append_to_statement_list_force (r, &stmt_list);
1680      /* We have an initializer, which might itself contain await exprs.  */
1681      await_init = tsi_stmt_ptr (tsi_last (stmt_list));
1682    }
1683
1684  /* Use the await_ready() call to test if we need to suspend.  */
1685  tree ready_cond = TREE_VEC_ELT (awaiter_calls, 0); /* await_ready().  */
1686  /* Convert to bool, if necessary.  */
1687  if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
1688    ready_cond = cp_convert (boolean_type_node, ready_cond,
1689			     tf_warning_or_error);
1690  /* Be aggressive in folding here, since there are a significant number of
1691     cases where the ready condition is constant.  */
1692  ready_cond = invert_truthvalue_loc (loc, ready_cond);
1693  ready_cond
1694    = build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, ready_cond);
1695
1696  tree body_list = NULL;
1697  tree susp_idx = build_int_cst (short_unsigned_type_node, data->index);
1698  r = build2_loc (loc, MODIFY_EXPR, short_unsigned_type_node, data->resume_idx,
1699		  susp_idx);
1700  r = coro_build_cvt_void_expr_stmt (r, loc);
1701  append_to_statement_list (r, &body_list);
1702
1703  /* Find out what we have to do with the awaiter's suspend method.
1704     [expr.await]
1705     (5.1) If the result of await-ready is false, the coroutine is considered
1706	   suspended. Then:
1707     (5.1.1) If the type of await-suspend is std::coroutine_handle<Z>,
1708	     await-suspend.resume() is evaluated.
1709     (5.1.2) if the type of await-suspend is bool, await-suspend is evaluated,
1710	     and the coroutine is resumed if the result is false.
1711     (5.1.3) Otherwise, await-suspend is evaluated.  */
1712
1713  tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend().  */
1714  tree susp_type = TREE_TYPE (suspend);
1715
1716  bool is_cont = false;
1717  /* NOTE: final suspend can't resume; the "resume" label in that case
1718     corresponds to implicit destruction.  */
1719  if (VOID_TYPE_P (susp_type))
1720    {
1721      /* We just call await_suspend() and hit the yield.  */
1722      suspend = coro_build_cvt_void_expr_stmt (suspend, loc);
1723      append_to_statement_list (suspend, &body_list);
1724    }
1725  else if (TREE_CODE (susp_type) == BOOLEAN_TYPE)
1726    {
1727      /* Boolean return, continue if the call returns false.  */
1728      suspend = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, suspend);
1729      suspend
1730	= build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, suspend);
1731      tree go_on = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
1732      r = build3_loc (loc, COND_EXPR, void_type_node, suspend, go_on,
1733		      empty_list);
1734      append_to_statement_list (r, &body_list);
1735    }
1736  else
1737    {
1738      r = build1_loc (loc, CONVERT_EXPR, void_coro_handle_type, suspend);
1739      r = build2_loc (loc, INIT_EXPR, void_coro_handle_type, data->conthand, r);
1740      r = build1 (CONVERT_EXPR, void_type_node, r);
1741      append_to_statement_list (r, &body_list);
1742      is_cont = true;
1743    }
1744
1745  tree d_l = build_address (destroy_label);
1746  tree r_l = build_address (resume_label);
1747  tree susp = build_address (data->cororet);
1748  tree cont = build_address (data->corocont);
1749  tree final_susp = build_int_cst (integer_type_node, is_final ? 1 : 0);
1750
1751  susp_idx = build_int_cst (integer_type_node, data->index);
1752
1753  tree sw = begin_switch_stmt ();
1754  tree cond = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
1755  DECL_ARTIFICIAL (cond) = 1;
1756  DECL_IGNORED_P (cond) = 1;
1757  layout_decl (cond, 0);
1758
1759  r = build_call_expr_internal_loc (loc, IFN_CO_YIELD, integer_type_node, 5,
1760				    susp_idx, final_susp, r_l, d_l,
1761				    data->coro_fp);
1762  r = build2 (INIT_EXPR, integer_type_node, cond, r);
1763  finish_switch_cond (r, sw);
1764  r = build_case_label (build_int_cst (integer_type_node, 0), NULL_TREE,
1765			create_anon_label_with_ctx (loc, actor));
1766  add_stmt (r); /* case 0: */
1767  /* Implement the suspend, a scope exit without clean ups.  */
1768  r = build_call_expr_internal_loc (loc, IFN_CO_SUSPN, void_type_node, 1,
1769				    is_cont ? cont : susp);
1770  r = coro_build_cvt_void_expr_stmt (r, loc);
1771  add_stmt (r); /*   goto ret;  */
1772  r = build_case_label (build_int_cst (integer_type_node, 1), NULL_TREE,
1773			create_anon_label_with_ctx (loc, actor));
1774  add_stmt (r); /* case 1:  */
1775  r = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
1776  add_stmt (r); /*  goto resume;  */
1777  r = build_case_label (NULL_TREE, NULL_TREE,
1778			create_anon_label_with_ctx (loc, actor));
1779  add_stmt (r); /* default:;  */
1780  r = build1_loc (loc, GOTO_EXPR, void_type_node, destroy_label);
1781  add_stmt (r); /* goto destroy;  */
1782
1783  /* part of finish switch.  */
1784  SWITCH_STMT_BODY (sw) = pop_stmt_list (SWITCH_STMT_BODY (sw));
1785  pop_switch ();
1786  tree scope = SWITCH_STMT_SCOPE (sw);
1787  SWITCH_STMT_SCOPE (sw) = NULL;
1788  r = do_poplevel (scope);
1789  append_to_statement_list (r, &body_list);
1790
1791  destroy_label = build_stmt (loc, LABEL_EXPR, destroy_label);
1792  append_to_statement_list (destroy_label, &body_list);
1793  if (needs_dtor)
1794    {
1795      tree dtor = build_special_member_call (var, complete_dtor_identifier,
1796					     NULL, await_type, LOOKUP_NORMAL,
1797					     tf_warning_or_error);
1798      append_to_statement_list (dtor, &body_list);
1799    }
1800  r = build1_loc (loc, GOTO_EXPR, void_type_node, data->cleanup);
1801  append_to_statement_list (r, &body_list);
1802
1803  r = build3_loc (loc, COND_EXPR, void_type_node, ready_cond, body_list,
1804		  empty_list);
1805
1806  append_to_statement_list (r, &stmt_list);
1807
1808  /* Resume point.  */
1809  resume_label = build_stmt (loc, LABEL_EXPR, resume_label);
1810  append_to_statement_list (resume_label, &stmt_list);
1811
1812  /* This will produce the value (if one is provided) from the co_await
1813     expression.  */
1814  tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume().  */
1815  if (REFERENCE_REF_P (resume_call))
1816    /* Sink to await_resume call_expr.  */
1817    resume_call = TREE_OPERAND (resume_call, 0);
1818
1819  *await_expr = resume_call; /* Replace the co_await expr with its result.  */
1820  append_to_statement_list_force (saved_statement, &stmt_list);
1821  /* Get a pointer to the revised statement.  */
1822  tree *revised = tsi_stmt_ptr (tsi_last (stmt_list));
1823  if (needs_dtor)
1824    {
1825      tree dtor = build_special_member_call (var, complete_dtor_identifier,
1826					     NULL, await_type, LOOKUP_NORMAL,
1827					     tf_warning_or_error);
1828      append_to_statement_list (dtor, &stmt_list);
1829    }
1830  data->index += 2;
1831
1832  /* Replace the original statement with the expansion.  */
1833  *stmt = stmt_list;
1834
1835  /* Now, if the awaitable had an initializer, expand any awaits that might
1836     be embedded in it.  */
1837  tree *aw_expr_ptr;
1838  if (await_init &&
1839      cp_walk_tree (await_init, co_await_find_in_subtree, &aw_expr_ptr, NULL))
1840    expand_one_await_expression (await_init, aw_expr_ptr, d);
1841
1842  /* Expand any more await expressions in the original statement.  */
1843  if (cp_walk_tree (revised, co_await_find_in_subtree, &aw_expr_ptr, NULL))
1844    expand_one_await_expression (revised, aw_expr_ptr, d);
1845
1846  return NULL;
1847}
1848
1849/* Check to see if a statement contains at least one await expression, if
1850   so, then process that.  */
1851
1852static tree
1853process_one_statement (tree *stmt, void *d)
1854{
1855  tree *aw_expr_ptr;
1856  if (cp_walk_tree (stmt, co_await_find_in_subtree, &aw_expr_ptr, NULL))
1857    expand_one_await_expression (stmt, aw_expr_ptr, d);
1858  return NULL_TREE;
1859}
1860
1861static tree
1862await_statement_expander (tree *stmt, int *do_subtree, void *d)
1863{
1864  tree res = NULL_TREE;
1865
1866  /* Process a statement at a time.  */
1867  if (STATEMENT_CLASS_P (*stmt) || TREE_CODE (*stmt) == BIND_EXPR)
1868    return NULL_TREE; /* Just process the sub-trees.  */
1869  else if (TREE_CODE (*stmt) == STATEMENT_LIST)
1870    {
1871      for (tree &s : tsi_range (*stmt))
1872	{
1873	  res = cp_walk_tree (&s, await_statement_expander,
1874			      d, NULL);
1875	  if (res)
1876	    return res;
1877	}
1878      *do_subtree = 0; /* Done subtrees.  */
1879    }
1880  else if (EXPR_P (*stmt))
1881    {
1882      process_one_statement (stmt, d);
1883      *do_subtree = 0; /* Done subtrees.  */
1884    }
1885
1886  /* Continue statement walk, where required.  */
1887  return res;
1888}
1889
1890/* Suspend point hash_map.  */
1891
1892struct suspend_point_info
1893{
1894  /* coro frame field type.  */
1895  tree awaitable_type;
1896  /* coro frame field name.  */
1897  tree await_field_id;
1898};
1899
1900static hash_map<tree, suspend_point_info> *suspend_points;
1901
1902struct await_xform_data
1903{
1904  tree actor_fn;   /* Decl for context.  */
1905  tree actor_frame;
1906};
1907
1908/* When we built the await expressions, we didn't know the coro frame
1909   layout, therefore no idea where to find the promise or where to put
1910   the awaitables.  Now we know these things, fill them in.  */
1911
1912static tree
1913transform_await_expr (tree await_expr, await_xform_data *xform)
1914{
1915  suspend_point_info *si = suspend_points->get (await_expr);
1916  location_t loc = EXPR_LOCATION (await_expr);
1917  if (!si)
1918    {
1919      error_at (loc, "no suspend point info for %qD", await_expr);
1920      return error_mark_node;
1921    }
1922
1923  /* So, on entry, we have:
1924     in : CO_AWAIT_EXPR (a, e_proxy, o, awr_call_vector, mode)
1925	  We no longer need a [it had diagnostic value, maybe?]
1926	  We need to replace the e_proxy in the awr_call.  */
1927
1928  tree coro_frame_type = TREE_TYPE (xform->actor_frame);
1929
1930  /* If we have a frame var for the awaitable, get a reference to it.  */
1931  proxy_replace data;
1932  if (si->await_field_id)
1933    {
1934      tree as_m
1935	 = lookup_member (coro_frame_type, si->await_field_id,
1936			  /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
1937      tree as = build_class_member_access_expr (xform->actor_frame, as_m,
1938						NULL_TREE, true,
1939						tf_warning_or_error);
1940
1941      /* Replace references to the instance proxy with the frame entry now
1942	 computed.  */
1943      data.from = TREE_OPERAND (await_expr, 1);
1944      data.to = as;
1945      cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1946
1947      /* .. and replace.  */
1948      TREE_OPERAND (await_expr, 1) = as;
1949    }
1950
1951  return await_expr;
1952}
1953
1954/* A wrapper for the transform_await_expr function so that it can be a
1955   callback from cp_walk_tree.  */
1956
1957static tree
1958transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
1959{
1960  /* Set actor function as new DECL_CONTEXT of label_decl.  */
1961  struct await_xform_data *xform = (struct await_xform_data *) d;
1962  if (TREE_CODE (*stmt) == LABEL_DECL
1963      && DECL_CONTEXT (*stmt) != xform->actor_fn)
1964    DECL_CONTEXT (*stmt) = xform->actor_fn;
1965
1966  /* We should have already lowered co_yields to their co_await.  */
1967  gcc_checking_assert (TREE_CODE (*stmt) != CO_YIELD_EXPR);
1968  if (TREE_CODE (*stmt) != CO_AWAIT_EXPR)
1969    return NULL_TREE;
1970
1971  tree await_expr = *stmt;
1972  *stmt = transform_await_expr (await_expr, xform);
1973  if (*stmt == error_mark_node)
1974    *do_subtree = 0;
1975  return NULL_TREE;
1976}
1977
1978/* This caches information that we determine about function params,
1979   their uses and copies in the coroutine frame.  */
1980
1981struct param_info
1982{
1983  tree field_id;     /* The name of the copy in the coroutine frame.  */
1984  tree copy_var;     /* The local var proxy for the frame copy.  */
1985  vec<tree *> *body_uses; /* Worklist of uses, void if there are none.  */
1986  tree frame_type;   /* The type used to represent this parm in the frame.  */
1987  tree orig_type;    /* The original type of the parm (not as passed).  */
1988  tree guard_var;    /* If we need a DTOR on exception, this bool guards it.  */
1989  tree fr_copy_dtor; /* If we need a DTOR on exception, this is it.  */
1990  bool by_ref;       /* Was passed by reference.  */
1991  bool pt_ref;       /* Was a pointer to object.  */
1992  bool rv_ref;       /* Was an rvalue ref.  */
1993  bool trivial_dtor; /* The frame type has a trivial DTOR.  */
1994  bool this_ptr;     /* Is 'this' */
1995  bool lambda_cobj;  /* Lambda capture object */
1996};
1997
1998struct local_var_info
1999{
2000  tree field_id;
2001  tree field_idx;
2002  tree frame_type;
2003  bool is_lambda_capture;
2004  bool is_static;
2005  bool has_value_expr_p;
2006  location_t def_loc;
2007};
2008
2009/* For figuring out what local variable usage we have.  */
2010struct local_vars_transform
2011{
2012  tree context;
2013  tree actor_frame;
2014  tree coro_frame_type;
2015  location_t loc;
2016  hash_map<tree, local_var_info> *local_var_uses;
2017};
2018
2019static tree
2020transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
2021{
2022  local_vars_transform *lvd = (local_vars_transform *) d;
2023
2024  /* For each var in this bind expr (that has a frame id, which means it was
2025     accessed), build a frame reference and add it as the DECL_VALUE_EXPR.  */
2026
2027  if (TREE_CODE (*stmt) == BIND_EXPR)
2028    {
2029      tree lvar;
2030      for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
2031	   lvar = DECL_CHAIN (lvar))
2032	{
2033	  bool existed;
2034	  local_var_info &local_var
2035	    = lvd->local_var_uses->get_or_insert (lvar, &existed);
2036	  gcc_checking_assert (existed);
2037
2038	  /* Re-write the variable's context to be in the actor func.  */
2039	  DECL_CONTEXT (lvar) = lvd->context;
2040
2041	  /* For capture proxies, this could include the decl value expr.  */
2042	  if (local_var.is_lambda_capture || local_var.has_value_expr_p)
2043	    continue; /* No frame entry for this.  */
2044
2045	  /* TODO: implement selective generation of fields when vars are
2046	     known not-used.  */
2047	  if (local_var.field_id == NULL_TREE)
2048	    continue; /* Wasn't used.  */
2049
2050	  tree fld_ref
2051	    = lookup_member (lvd->coro_frame_type, local_var.field_id,
2052			     /*protect=*/1, /*want_type=*/0,
2053			     tf_warning_or_error);
2054	  tree fld_idx = build3_loc (lvd->loc, COMPONENT_REF, TREE_TYPE (lvar),
2055				     lvd->actor_frame, fld_ref, NULL_TREE);
2056	  local_var.field_idx = fld_idx;
2057	  SET_DECL_VALUE_EXPR (lvar, fld_idx);
2058	  DECL_HAS_VALUE_EXPR_P (lvar) = true;
2059	}
2060      cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
2061      *do_subtree = 0; /* We've done the body already.  */
2062      return NULL_TREE;
2063    }
2064  return NULL_TREE;
2065}
2066
2067/* A helper to build the frame DTOR.
2068   [dcl.fct.def.coroutine] / 12
2069   The deallocation function���s name is looked up in the scope of the promise
2070   type.  If this lookup fails, the deallocation function���s name is looked up
2071   in the global scope.  If deallocation function lookup finds both a usual
2072   deallocation function with only a pointer parameter and a usual
2073   deallocation function with both a pointer parameter and a size parameter,
2074   then the selected deallocation function shall be the one with two
2075   parameters.  Otherwise, the selected deallocation function shall be the
2076   function with one parameter.  If no usual deallocation function is found
2077   the program is ill-formed.  The selected deallocation function shall be
2078   called with the address of the block of storage to be reclaimed as its
2079   first argument.  If a deallocation function with a parameter of type
2080   std::size_t is used, the size of the block is passed as the corresponding
2081   argument.  */
2082
2083static tree
2084coro_get_frame_dtor (tree coro_fp, tree orig, tree frame_size,
2085		     tree promise_type, location_t loc)
2086{
2087  tree del_coro_fr = NULL_TREE;
2088  tree frame_arg = build1 (CONVERT_EXPR, ptr_type_node, coro_fp);
2089  tree delname = ovl_op_identifier (false, DELETE_EXPR);
2090  tree fns = lookup_promise_method (orig, delname, loc,
2091					/*musthave=*/false);
2092  if (fns && BASELINK_P (fns))
2093    {
2094      /* Look for sized version first, since this takes precedence.  */
2095      vec<tree, va_gc> *args = make_tree_vector ();
2096      vec_safe_push (args, frame_arg);
2097      vec_safe_push (args, frame_size);
2098      tree dummy_promise = build_dummy_object (promise_type);
2099
2100      /* It's OK to fail for this one... */
2101      del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2102					   NULL_TREE, LOOKUP_NORMAL, NULL,
2103					   tf_none);
2104
2105      if (!del_coro_fr || del_coro_fr == error_mark_node)
2106	{
2107	  release_tree_vector (args);
2108	  args = make_tree_vector_single (frame_arg);
2109	  del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2110					       NULL_TREE, LOOKUP_NORMAL, NULL,
2111					       tf_none);
2112	}
2113
2114      /* But one of them must succeed, or the program is ill-formed.  */
2115      if (!del_coro_fr || del_coro_fr == error_mark_node)
2116	{
2117	  error_at (loc, "%qE is provided by %qT but is not usable with"
2118		  " the function signature %qD", delname, promise_type, orig);
2119	  del_coro_fr = error_mark_node;
2120	}
2121    }
2122  else
2123    {
2124      del_coro_fr = build_op_delete_call (DELETE_EXPR, frame_arg, frame_size,
2125					  /*global_p=*/true, /*placement=*/NULL,
2126					  /*alloc_fn=*/NULL,
2127					  tf_warning_or_error);
2128      if (!del_coro_fr || del_coro_fr == error_mark_node)
2129	del_coro_fr = error_mark_node;
2130    }
2131  return del_coro_fr;
2132}
2133
2134/* The actor transform.  */
2135
2136static void
2137build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2138		tree orig, hash_map<tree, local_var_info> *local_var_uses,
2139		vec<tree, va_gc> *param_dtor_list,
2140		tree resume_idx_var, unsigned body_count, tree frame_size)
2141{
2142  verify_stmt_tree (fnbody);
2143  /* Some things we inherit from the original function.  */
2144  tree handle_type = get_coroutine_handle_type (orig);
2145  tree promise_type = get_coroutine_promise_type (orig);
2146  tree promise_proxy = get_coroutine_promise_proxy (orig);
2147
2148  /* One param, the coro frame pointer.  */
2149  tree actor_fp = DECL_ARGUMENTS (actor);
2150
2151  /* We have a definition here.  */
2152  TREE_STATIC (actor) = 1;
2153
2154  tree actor_outer = push_stmt_list ();
2155  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
2156  tree stmt = begin_compound_stmt (BCS_FN_BODY);
2157
2158  tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
2159  tree top_block = make_node (BLOCK);
2160  BIND_EXPR_BLOCK (actor_bind) = top_block;
2161
2162  tree continuation = coro_build_artificial_var (loc, coro_actor_continue_id,
2163						 void_coro_handle_type, actor,
2164						 NULL_TREE);
2165
2166  BIND_EXPR_VARS (actor_bind) = continuation;
2167  BLOCK_VARS (top_block) = BIND_EXPR_VARS (actor_bind) ;
2168
2169  /* Link in the block associated with the outer scope of the re-written
2170     function body.  */
2171  tree first = expr_first (fnbody);
2172  gcc_checking_assert (first && TREE_CODE (first) == BIND_EXPR);
2173  tree block = BIND_EXPR_BLOCK (first);
2174  gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
2175  gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE);
2176  BLOCK_SUPERCONTEXT (block) = top_block;
2177  BLOCK_SUBBLOCKS (top_block) = block;
2178
2179  add_stmt (actor_bind);
2180  tree actor_body = push_stmt_list ();
2181
2182  /* The entry point for the actor code from the ramp.  */
2183  tree actor_begin_label
2184    = create_named_label_with_ctx (loc, "actor.begin", actor);
2185  tree actor_frame = build1_loc (loc, INDIRECT_REF, coro_frame_type, actor_fp);
2186
2187  /* Declare the continuation handle.  */
2188  add_decl_expr (continuation);
2189
2190  /* Re-write local vars, similarly.  */
2191  local_vars_transform xform_vars_data
2192    = {actor, actor_frame, coro_frame_type, loc, local_var_uses};
2193  cp_walk_tree (&fnbody, transform_local_var_uses, &xform_vars_data, NULL);
2194
2195  tree rat_field = lookup_member (coro_frame_type, coro_resume_index_id,
2196				  1, 0, tf_warning_or_error);
2197  tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, actor_frame,
2198		     rat_field, NULL_TREE);
2199
2200  tree ret_label
2201    = create_named_label_with_ctx (loc, "actor.suspend.ret", actor);
2202
2203  tree continue_label
2204    = create_named_label_with_ctx (loc, "actor.continue.ret", actor);
2205
2206  tree lsb_if = begin_if_stmt ();
2207  tree chkb0 = build2 (BIT_AND_EXPR, short_unsigned_type_node, rat,
2208		       build_int_cst (short_unsigned_type_node, 1));
2209  chkb0 = build2 (NE_EXPR, short_unsigned_type_node, chkb0,
2210		  build_int_cst (short_unsigned_type_node, 0));
2211  finish_if_stmt_cond (chkb0, lsb_if);
2212
2213  tree destroy_dispatcher = begin_switch_stmt ();
2214  finish_switch_cond (rat, destroy_dispatcher);
2215  tree ddeflab = build_case_label (NULL_TREE, NULL_TREE,
2216				   create_anon_label_with_ctx (loc, actor));
2217  add_stmt (ddeflab);
2218  tree b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2219  b = coro_build_cvt_void_expr_stmt (b, loc);
2220  add_stmt (b);
2221
2222  /* The destroy point numbered #1 is special, in that it is reached from a
2223     coroutine that is suspended after re-throwing from unhandled_exception().
2224     This label just invokes the cleanup of promise, param copies and the
2225     frame itself.  */
2226  tree del_promise_label
2227    = create_named_label_with_ctx (loc, "coro.delete.promise", actor);
2228  b = build_case_label (build_int_cst (short_unsigned_type_node, 1), NULL_TREE,
2229			create_anon_label_with_ctx (loc, actor));
2230  add_stmt (b);
2231  add_stmt (build_stmt (loc, GOTO_EXPR, del_promise_label));
2232
2233  short unsigned lab_num = 3;
2234  for (unsigned destr_pt = 0; destr_pt < body_count; destr_pt++)
2235    {
2236      tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2237      b = build_case_label (l_num, NULL_TREE,
2238			    create_anon_label_with_ctx (loc, actor));
2239      add_stmt (b);
2240      b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2241					l_num);
2242      b = coro_build_cvt_void_expr_stmt (b, loc);
2243      add_stmt (b);
2244      b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (ddeflab));
2245      add_stmt (b);
2246      lab_num += 2;
2247    }
2248
2249  /* Insert the prototype dispatcher.  */
2250  finish_switch_stmt (destroy_dispatcher);
2251
2252  finish_then_clause (lsb_if);
2253  begin_else_clause (lsb_if);
2254
2255  tree dispatcher = begin_switch_stmt ();
2256  finish_switch_cond (rat, dispatcher);
2257  b = build_case_label (build_int_cst (short_unsigned_type_node, 0), NULL_TREE,
2258			create_anon_label_with_ctx (loc, actor));
2259  add_stmt (b);
2260  b = build1 (GOTO_EXPR, void_type_node, actor_begin_label);
2261  add_stmt (b);
2262
2263  tree rdeflab = build_case_label (NULL_TREE, NULL_TREE,
2264				   create_anon_label_with_ctx (loc, actor));
2265  add_stmt (rdeflab);
2266  b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2267  b = coro_build_cvt_void_expr_stmt (b, loc);
2268  add_stmt (b);
2269
2270  lab_num = 2;
2271  /* The final resume should be made to hit the default (trap, UB) entry
2272     although it will be unreachable via the normal entry point, since that
2273     is set to NULL on reaching final suspend.  */
2274  for (unsigned resu_pt = 0; resu_pt < body_count; resu_pt++)
2275    {
2276      tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2277      b = build_case_label (l_num, NULL_TREE,
2278			    create_anon_label_with_ctx (loc, actor));
2279      add_stmt (b);
2280      b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2281					l_num);
2282      b = coro_build_cvt_void_expr_stmt (b, loc);
2283      add_stmt (b);
2284      b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (rdeflab));
2285      add_stmt (b);
2286      lab_num += 2;
2287    }
2288
2289  /* Insert the prototype dispatcher.  */
2290  finish_switch_stmt (dispatcher);
2291  finish_else_clause (lsb_if);
2292
2293  finish_if_stmt (lsb_if);
2294
2295  tree r = build_stmt (loc, LABEL_EXPR, actor_begin_label);
2296  add_stmt (r);
2297
2298  /* actor's coroutine 'self handle'.  */
2299  tree ash_m = lookup_member (coro_frame_type, coro_self_handle_id, 1,
2300			      0, tf_warning_or_error);
2301  tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
2302					     false, tf_warning_or_error);
2303  /* So construct the self-handle from the frame address.  */
2304  tree hfa_m = lookup_member (handle_type, coro_from_address_identifier, 1,
2305			      0, tf_warning_or_error);
2306
2307  r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
2308  vec<tree, va_gc> *args = make_tree_vector_single (r);
2309  tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
2310				    NULL, tf_warning_or_error);
2311  r = build2 (INIT_EXPR, handle_type, ash, hfa);
2312  r = coro_build_cvt_void_expr_stmt (r, loc);
2313  add_stmt (r);
2314  release_tree_vector (args);
2315
2316  /* Now we know the real promise, and enough about the frame layout to
2317     decide where to put things.  */
2318
2319  await_xform_data xform = {actor, actor_frame};
2320
2321  /* Transform the await expressions in the function body.  Only do each
2322     await tree once!  */
2323  hash_set<tree> pset;
2324  cp_walk_tree (&fnbody, transform_await_wrapper, &xform, &pset);
2325
2326  /* Add in our function body with the co_returns rewritten to final form.  */
2327  add_stmt (fnbody);
2328
2329  /* now do the tail of the function.  */
2330  r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2331  add_stmt (r);
2332
2333  /* Destructors for the things we built explicitly.  */
2334  r = build_special_member_call (promise_proxy, complete_dtor_identifier, NULL,
2335				 promise_type, LOOKUP_NORMAL,
2336				 tf_warning_or_error);
2337  add_stmt (r);
2338
2339  tree del_frame_label
2340    = create_named_label_with_ctx (loc, "coro.delete.frame", actor);
2341  r = build_stmt (loc, LABEL_EXPR, del_frame_label);
2342  add_stmt (r);
2343
2344  /* Here deallocate the frame (if we allocated it), which we will have at
2345     present.  */
2346  tree fnf_m
2347    = lookup_member (coro_frame_type, coro_frame_needs_free_id, 1,
2348		     0, tf_warning_or_error);
2349  tree fnf2_x = build_class_member_access_expr (actor_frame, fnf_m, NULL_TREE,
2350						false, tf_warning_or_error);
2351
2352  tree need_free_if = begin_if_stmt ();
2353  fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x);
2354  tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node);
2355  finish_if_stmt_cond (cmp, need_free_if);
2356  if (param_dtor_list != NULL)
2357    {
2358      int i;
2359      tree pid;
2360      FOR_EACH_VEC_ELT (*param_dtor_list, i, pid)
2361	{
2362	  tree m
2363	    = lookup_member (coro_frame_type, pid, 1, 0, tf_warning_or_error);
2364	  tree a = build_class_member_access_expr (actor_frame, m, NULL_TREE,
2365						   false, tf_warning_or_error);
2366	  tree t = TREE_TYPE (a);
2367	  tree dtor;
2368	  dtor
2369	    = build_special_member_call (a, complete_dtor_identifier, NULL, t,
2370					 LOOKUP_NORMAL, tf_warning_or_error);
2371	  add_stmt (dtor);
2372	}
2373    }
2374
2375  /* Build the frame DTOR.  */
2376  tree del_coro_fr = coro_get_frame_dtor (actor_fp, orig, frame_size,
2377					  promise_type, loc);
2378  finish_expr_stmt (del_coro_fr);
2379  finish_then_clause (need_free_if);
2380  tree scope = IF_SCOPE (need_free_if);
2381  IF_SCOPE (need_free_if) = NULL;
2382  r = do_poplevel (scope);
2383  add_stmt (r);
2384
2385  /* done.  */
2386  r = build_stmt (loc, RETURN_EXPR, NULL);
2387  suppress_warning (r); /* We don't want a warning about this.  */
2388  r = maybe_cleanup_point_expr_void (r);
2389  add_stmt (r);
2390
2391  /* This is the suspend return point.  */
2392  r = build_stmt (loc, LABEL_EXPR, ret_label);
2393  add_stmt (r);
2394
2395  r = build_stmt (loc, RETURN_EXPR, NULL);
2396  suppress_warning (r); /* We don't want a warning about this.  */
2397  r = maybe_cleanup_point_expr_void (r);
2398  add_stmt (r);
2399
2400  /* This is the 'continuation' return point.  For such a case we have a coro
2401     handle (from the await_suspend() call) and we want handle.resume() to
2402     execute as a tailcall allowing arbitrary chaining of coroutines.  */
2403  r = build_stmt (loc, LABEL_EXPR, continue_label);
2404  add_stmt (r);
2405
2406  /* We want to force a tail-call even for O0/1, so this expands the resume
2407     call into its underlying implementation.  */
2408  tree addr = lookup_member (void_coro_handle_type, coro_address_identifier,
2409			       1, 0, tf_warning_or_error);
2410  addr = build_new_method_call (continuation, addr, NULL, NULL_TREE,
2411				  LOOKUP_NORMAL, NULL, tf_warning_or_error);
2412  tree resume = build_call_expr_loc
2413    (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
2414
2415  /* In order to support an arbitrary number of coroutine continuations,
2416     we must tail call them.  However, some targets do not support indirect
2417     tail calls to arbitrary callees.  See PR94359.  */
2418  CALL_EXPR_TAILCALL (resume) = true;
2419  resume = coro_build_cvt_void_expr_stmt (resume, loc);
2420  add_stmt (resume);
2421
2422  r = build_stmt (loc, RETURN_EXPR, NULL);
2423  gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
2424  add_stmt (r);
2425
2426  /* We've now rewritten the tree and added the initial and final
2427     co_awaits.  Now pass over the tree and expand the co_awaits.  */
2428
2429  coro_aw_data data = {actor, actor_fp, resume_idx_var, NULL_TREE,
2430		       ash, del_promise_label, ret_label,
2431		       continue_label, continuation, 2};
2432  cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);
2433
2434  BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
2435  TREE_SIDE_EFFECTS (actor_bind) = true;
2436
2437  finish_compound_stmt (stmt);
2438  DECL_SAVED_TREE (actor) = pop_stmt_list (actor_outer);
2439  verify_stmt_tree (DECL_SAVED_TREE (actor));
2440}
2441
2442/* The prototype 'destroy' function :
2443   frame->__Coro_resume_index |= 1;
2444   actor (frame);  */
2445
2446static void
2447build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
2448		  tree actor)
2449{
2450  /* One param, the coro frame pointer.  */
2451  tree destr_fp = DECL_ARGUMENTS (destroy);
2452
2453  /* We have a definition here.  */
2454  TREE_STATIC (destroy) = 1;
2455
2456  tree destr_outer = push_stmt_list ();
2457  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
2458  tree dstr_stmt = begin_compound_stmt (BCS_FN_BODY);
2459
2460  tree destr_frame = build1 (INDIRECT_REF, coro_frame_type, destr_fp);
2461
2462  tree rat_field = lookup_member (coro_frame_type, coro_resume_index_id,
2463				  1, 0, tf_warning_or_error);
2464  tree rat = build3 (COMPONENT_REF, short_unsigned_type_node,
2465			 destr_frame, rat_field, NULL_TREE);
2466
2467  /* _resume_at |= 1 */
2468  tree dstr_idx = build2 (BIT_IOR_EXPR, short_unsigned_type_node, rat,
2469			  build_int_cst (short_unsigned_type_node, 1));
2470  tree r = build2 (MODIFY_EXPR, short_unsigned_type_node, rat, dstr_idx);
2471  r = coro_build_cvt_void_expr_stmt (r, loc);
2472  add_stmt (r);
2473
2474  /* So .. call the actor ..  */
2475  r = build_call_expr_loc (loc, actor, 1, destr_fp);
2476  r = coro_build_cvt_void_expr_stmt (r, loc);
2477  add_stmt (r);
2478
2479  /* done. */
2480  r = build_stmt (loc, RETURN_EXPR, NULL);
2481  r = maybe_cleanup_point_expr_void (r);
2482  add_stmt (r);
2483
2484  finish_compound_stmt (dstr_stmt);
2485  DECL_SAVED_TREE (destroy) = pop_stmt_list (destr_outer);
2486}
2487
2488/* Helper that returns an identifier for an appended extension to the
2489   current un-mangled function name.  */
2490
2491static tree
2492get_fn_local_identifier (tree orig, const char *append)
2493{
2494  /* Figure out the bits we need to generate names for the outlined things
2495     For consistency, this needs to behave the same way as
2496     ASM_FORMAT_PRIVATE_NAME does. */
2497  tree nm = DECL_NAME (orig);
2498  const char *sep, *pfx = "";
2499#ifndef NO_DOT_IN_LABEL
2500  sep = ".";
2501#else
2502#ifndef NO_DOLLAR_IN_LABEL
2503  sep = "$";
2504#else
2505  sep = "_";
2506  pfx = "__";
2507#endif
2508#endif
2509
2510  char *an;
2511  if (DECL_ASSEMBLER_NAME (orig))
2512    an = ACONCAT ((IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig)), sep, append,
2513		   (char *) 0));
2514  else if (DECL_USE_TEMPLATE (orig) && DECL_TEMPLATE_INFO (orig)
2515	   && DECL_TI_ARGS (orig))
2516    {
2517      tree tpl_args = DECL_TI_ARGS (orig);
2518      an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), (char *) 0));
2519      for (int i = 0; i < TREE_VEC_LENGTH (tpl_args); ++i)
2520	{
2521	  tree typ = DECL_NAME (TYPE_NAME (TREE_VEC_ELT (tpl_args, i)));
2522	  an = ACONCAT ((an, sep, IDENTIFIER_POINTER (typ), (char *) 0));
2523	}
2524      an = ACONCAT ((an, sep, append, (char *) 0));
2525    }
2526  else
2527    an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), sep, append, (char *) 0));
2528
2529  return get_identifier (an);
2530}
2531
2532/* Build an initial or final await initialized from the promise
2533   initial_suspend or final_suspend expression.  */
2534
2535static tree
2536build_init_or_final_await (location_t loc, bool is_final)
2537{
2538  tree suspend_alt = is_final ? coro_final_suspend_identifier
2539			      : coro_initial_suspend_identifier;
2540
2541  tree setup_call
2542    = coro_build_promise_expression (current_function_decl, NULL, suspend_alt,
2543				     loc, NULL, /*musthave=*/true);
2544
2545  /* Check for noexcept on the final_suspend call.  */
2546  if (flag_exceptions && is_final && setup_call != error_mark_node
2547      && coro_diagnose_throwing_final_aw_expr (setup_call))
2548    return error_mark_node;
2549
2550  /* So build the co_await for this */
2551  /* For initial/final suspends the call is "a" per [expr.await] 3.2.  */
2552  return build_co_await (loc, setup_call, (is_final ? FINAL_SUSPEND_POINT
2553						    : INITIAL_SUSPEND_POINT));
2554}
2555
2556/* Callback to record the essential data for each await point found in the
2557   function.  */
2558
2559static bool
2560register_await_info (tree await_expr, tree aw_type, tree aw_nam)
2561{
2562  bool seen;
2563  suspend_point_info &s
2564    = suspend_points->get_or_insert (await_expr, &seen);
2565  if (seen)
2566    {
2567      warning_at (EXPR_LOCATION (await_expr), 0, "duplicate info for %qE",
2568		await_expr);
2569      return false;
2570    }
2571  s.awaitable_type = aw_type;
2572  s.await_field_id = aw_nam;
2573  return true;
2574}
2575
2576/* This data set is used when analyzing statements for await expressions.  */
2577
2578struct susp_frame_data
2579{
2580  /* Function-wide.  */
2581  tree *field_list; /* The current coroutine frame field list.  */
2582  tree handle_type; /* The self-handle type for this coroutine.  */
2583  tree fs_label;    /* The destination for co_returns.  */
2584  vec<tree, va_gc> *block_stack; /* Track block scopes.  */
2585  vec<tree, va_gc> *bind_stack;  /* Track current bind expr.  */
2586  unsigned await_number;	 /* Which await in the function.  */
2587  unsigned cond_number;		 /* Which replaced condition in the fn.  */
2588  /* Temporary values for one statement or expression being analyzed.  */
2589  hash_set<tree> captured_temps; /* The suspend captured these temps.  */
2590  vec<tree, va_gc> *to_replace;  /* The VAR decls to replace.  */
2591  hash_set<tree> *truth_aoif_to_expand; /* The set of TRUTH exprs to expand.  */
2592  unsigned saw_awaits;		 /* Count of awaits in this statement  */
2593  bool captures_temporary;	 /* This expr captures temps by ref.  */
2594  bool needs_truth_if_exp;	 /* We must expand a truth_if expression.  */
2595  bool has_awaiter_init;	 /* We must handle initializing an awaiter.  */
2596};
2597
2598/* If this is an await expression, then count it (both uniquely within the
2599   function and locally within a single statement).  */
2600
2601static tree
2602register_awaits (tree *stmt, int *, void *d)
2603{
2604  tree aw_expr = *stmt;
2605
2606  /* We should have already lowered co_yields to their co_await.  */
2607  gcc_checking_assert (TREE_CODE (aw_expr) != CO_YIELD_EXPR);
2608
2609  if (TREE_CODE (aw_expr) != CO_AWAIT_EXPR)
2610    return NULL_TREE;
2611
2612  /* Count how many awaits the current expression contains.  */
2613  susp_frame_data *data = (susp_frame_data *) d;
2614  data->saw_awaits++;
2615  /* Each await suspend context is unique, this is a function-wide value.  */
2616  data->await_number++;
2617
2618  /* Awaitables should either be user-locals or promoted to coroutine frame
2619     entries at this point, and their initializers should have been broken
2620     out.  */
2621  tree aw = TREE_OPERAND (aw_expr, 1);
2622  gcc_checking_assert (!TREE_OPERAND (aw_expr, 2));
2623
2624  tree aw_field_type = TREE_TYPE (aw);
2625  tree aw_field_nam = NULL_TREE;
2626  register_await_info (aw_expr, aw_field_type, aw_field_nam);
2627
2628  /* Rewrite target expressions on the await_suspend () to remove extraneous
2629     cleanups for the awaitables, which are now promoted to frame vars and
2630     managed via that.  */
2631  tree v = TREE_OPERAND (aw_expr, 3);
2632  tree o = TREE_VEC_ELT (v, 1);
2633  if (TREE_CODE (o) == TARGET_EXPR)
2634    TREE_VEC_ELT (v, 1) = get_target_expr (TREE_OPERAND (o, 1));
2635  return NULL_TREE;
2636}
2637
2638/* There are cases where any await expression is relevant.  */
2639static tree
2640find_any_await (tree *stmt, int *dosub, void *d)
2641{
2642  if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
2643    {
2644      *dosub = 0; /* We don't need to consider this any further.  */
2645      tree **p = (tree **) d;
2646      *p = stmt;
2647      return *stmt;
2648    }
2649  return NULL_TREE;
2650}
2651
2652static bool
2653tmp_target_expr_p (tree t)
2654{
2655  if (TREE_CODE (t) != TARGET_EXPR)
2656    return false;
2657  tree v = TREE_OPERAND (t, 0);
2658  if (!DECL_ARTIFICIAL (v))
2659    return false;
2660  if (DECL_NAME (v))
2661    return false;
2662  return true;
2663}
2664
2665/* Structure to record sub-expressions that need to be handled by the
2666   statement flattener.  */
2667
2668struct coro_interesting_subtree
2669{
2670  tree* entry;
2671  hash_set<tree> *temps_used;
2672};
2673
2674/* tree-walk callback that returns the first encountered sub-expression of
2675   a kind that needs to be handled specifically by the statement flattener.  */
2676
2677static tree
2678find_interesting_subtree (tree *expr_p, int *dosub, void *d)
2679{
2680  tree expr = *expr_p;
2681  coro_interesting_subtree *p = (coro_interesting_subtree *)d;
2682  if (TREE_CODE (expr) == CO_AWAIT_EXPR)
2683    {
2684      *dosub = 0; /* We don't need to consider this any further.  */
2685      if (TREE_OPERAND (expr, 2))
2686	{
2687	  p->entry = expr_p;
2688	  return expr;
2689	}
2690    }
2691  else if (tmp_target_expr_p (expr)
2692	   && !p->temps_used->contains (expr))
2693    {
2694      p->entry = expr_p;
2695      return expr;
2696    }
2697
2698  return NULL_TREE;
2699}
2700
2701/* Node for a doubly-linked list of promoted variables and their
2702   initializers.  When the initializer is a conditional expression
2703   the 'then' and 'else' clauses are represented by a linked list
2704   attached to then_cl and else_cl respectively.  */
2705
2706struct var_nest_node
2707{
2708  var_nest_node () = default;
2709  var_nest_node (tree v, tree i, var_nest_node *p, var_nest_node *n)
2710    : var(v), init(i), prev(p), next(n), then_cl (NULL), else_cl (NULL)
2711    {
2712      if (p)
2713	p->next = this;
2714      if (n)
2715	n->prev = this;
2716    }
2717  tree var;
2718  tree init;
2719  var_nest_node *prev;
2720  var_nest_node *next;
2721  var_nest_node *then_cl;
2722  var_nest_node *else_cl;
2723};
2724
2725/* This is called for single statements from the co-await statement walker.
2726   It checks to see if the statement contains any initializers for awaitables
2727   and if any of these capture items by reference.  */
2728
2729static void
2730flatten_await_stmt (var_nest_node *n, hash_set<tree> *promoted,
2731		    hash_set<tree> *temps_used, tree *replace_in)
2732{
2733  bool init_expr = false;
2734  switch (TREE_CODE (n->init))
2735    {
2736      default: break;
2737      /* Compound expressions must be flattened specifically.  */
2738      case COMPOUND_EXPR:
2739	{
2740	  tree first = TREE_OPERAND (n->init, 0);
2741	  n->init = TREE_OPERAND (n->init, 1);
2742	  var_nest_node *ins
2743	    = new var_nest_node(NULL_TREE, first, n->prev, n);
2744	  /* The compiler (but not the user) can generate temporaries with
2745	     uses in the second arm of a compound expr.  */
2746	  flatten_await_stmt (ins, promoted, temps_used, &n->init);
2747	  flatten_await_stmt (n, promoted, temps_used, NULL);
2748	  /* The two arms have been processed separately.  */
2749	  return;
2750	}
2751	break;
2752      /* Handle conditional expressions.  */
2753      case INIT_EXPR:
2754	init_expr = true;
2755	/* FALLTHROUGH */
2756      case MODIFY_EXPR:
2757	{
2758	  tree old_expr = TREE_OPERAND (n->init, 1);
2759	  if (TREE_CODE (old_expr) == COMPOUND_EXPR)
2760	    {
2761	      tree first = TREE_OPERAND (old_expr, 0);
2762	      TREE_OPERAND (n->init, 1) = TREE_OPERAND (old_expr, 1);
2763	      var_nest_node *ins
2764		= new var_nest_node(NULL_TREE, first, n->prev, n);
2765	      flatten_await_stmt (ins, promoted, temps_used,
2766				  &TREE_OPERAND (n->init, 1));
2767	      flatten_await_stmt (n, promoted, temps_used, NULL);
2768	      return;
2769	    }
2770	  if (TREE_CODE (old_expr) != COND_EXPR)
2771	    break;
2772	  /* Reconstruct x = t ? y : z;
2773	     as (void) t ? x = y : x = z;  */
2774	  tree var = TREE_OPERAND (n->init, 0);
2775	  tree var_type = TREE_TYPE (var);
2776	  tree cond = COND_EXPR_COND (old_expr);
2777	  /* We are allowed a void type throw in one or both of the cond
2778	     expr arms.  */
2779	  tree then_cl = COND_EXPR_THEN (old_expr);
2780	  if (!VOID_TYPE_P (TREE_TYPE (then_cl)))
2781	    {
2782	      gcc_checking_assert (TREE_CODE (then_cl) != STATEMENT_LIST);
2783	      then_cl
2784		= build2 (init_expr ? INIT_EXPR : MODIFY_EXPR, var_type,
2785			  var, then_cl);
2786	    }
2787	  tree else_cl = COND_EXPR_ELSE (old_expr);
2788	  if (!VOID_TYPE_P (TREE_TYPE (else_cl)))
2789	    {
2790	      gcc_checking_assert (TREE_CODE (else_cl) != STATEMENT_LIST);
2791	      else_cl
2792		= build2 (init_expr ? INIT_EXPR : MODIFY_EXPR, var_type,
2793			  var, else_cl);
2794	    }
2795	  n->init = build3 (COND_EXPR, var_type, cond, then_cl, else_cl);
2796	}
2797	/* FALLTHROUGH */
2798      case COND_EXPR:
2799	{
2800	  tree *found;
2801	  tree cond = COND_EXPR_COND (n->init);
2802	  /* If the condition contains an await expression, then we need to
2803	     set that first and use a separate var.  */
2804	  if (cp_walk_tree (&cond, find_any_await, &found, NULL))
2805	    {
2806	      tree cond_type = TREE_TYPE (cond);
2807	      tree cond_var  = build_lang_decl (VAR_DECL, NULL_TREE, cond_type);
2808	      DECL_ARTIFICIAL (cond_var) = true;
2809	      layout_decl (cond_var, 0);
2810	      gcc_checking_assert (!TYPE_NEEDS_CONSTRUCTING (cond_type));
2811	      cond = build2 (INIT_EXPR, cond_type, cond_var, cond);
2812	      var_nest_node *ins
2813		= new var_nest_node (cond_var, cond, n->prev, n);
2814	      COND_EXPR_COND (n->init) = cond_var;
2815	      flatten_await_stmt (ins, promoted, temps_used, NULL);
2816	    }
2817
2818	  n->then_cl
2819	    = new var_nest_node (n->var, COND_EXPR_THEN (n->init), NULL, NULL);
2820	  n->else_cl
2821	    = new var_nest_node (n->var, COND_EXPR_ELSE (n->init), NULL, NULL);
2822	  flatten_await_stmt (n->then_cl, promoted, temps_used, NULL);
2823	  /* Point to the start of the flattened code.  */
2824	  while (n->then_cl->prev)
2825	    n->then_cl = n->then_cl->prev;
2826	  flatten_await_stmt (n->else_cl, promoted, temps_used, NULL);
2827	  while (n->else_cl->prev)
2828	    n->else_cl = n->else_cl->prev;
2829	  return;
2830	}
2831	break;
2832    }
2833  coro_interesting_subtree v = { NULL, temps_used };
2834  tree t = cp_walk_tree (&n->init, find_interesting_subtree, (void *)&v, NULL);
2835  if (!t)
2836    return;
2837  switch (TREE_CODE (t))
2838    {
2839      default: break;
2840      case CO_AWAIT_EXPR:
2841	{
2842	  /* Await expressions with initializers have a compiler-temporary
2843	     as the awaitable.  'promote' this.  */
2844	  tree var = TREE_OPERAND (t, 1);
2845	  bool already_present = promoted->add (var);
2846	  gcc_checking_assert (!already_present);
2847	  tree init = TREE_OPERAND (t, 2);
2848	  switch (TREE_CODE (init))
2849	    {
2850	      default: break;
2851	      case INIT_EXPR:
2852	      case MODIFY_EXPR:
2853		{
2854		  tree inner = TREE_OPERAND (init, 1);
2855		  /* We can have non-lvalue-expressions here, but when we see
2856		     a target expression, mark it as already used.  */
2857		  if (TREE_CODE (inner) == TARGET_EXPR)
2858		    {
2859		      temps_used->add (inner);
2860		      gcc_checking_assert
2861			(TREE_CODE (TREE_OPERAND (inner, 1)) != COND_EXPR);
2862		    }
2863		}
2864		break;
2865	      case CALL_EXPR:
2866		/* If this is a call and not a CTOR, then we didn't expect it.  */
2867		gcc_checking_assert
2868		  (DECL_CONSTRUCTOR_P (TREE_OPERAND (CALL_EXPR_FN (init), 0)));
2869		break;
2870	    }
2871	  var_nest_node *ins = new var_nest_node (var, init, n->prev, n);
2872	  TREE_OPERAND (t, 2) = NULL_TREE;
2873	  flatten_await_stmt (ins, promoted, temps_used, NULL);
2874	  flatten_await_stmt (n, promoted, temps_used, NULL);
2875	  return;
2876	}
2877	break;
2878      case TARGET_EXPR:
2879	{
2880	  /* We have a temporary; promote it, but allow for the idiom in code
2881	     generated by the compiler like
2882	     a = (target_expr produces temp, op uses temp).  */
2883	  tree init = t;
2884	  temps_used->add (init);
2885	  tree var_type = TREE_TYPE (init);
2886	  char *buf = xasprintf ("T%03u", (unsigned) temps_used->elements ());
2887	  tree var = build_lang_decl (VAR_DECL, get_identifier (buf), var_type);
2888	  DECL_ARTIFICIAL (var) = true;
2889	  free (buf);
2890	  bool already_present = promoted->add (var);
2891	  gcc_checking_assert (!already_present);
2892	  tree inner = TREE_OPERAND (init, 1);
2893	  gcc_checking_assert (TREE_CODE (inner) != COND_EXPR);
2894	  init = cp_build_modify_expr (input_location, var, INIT_EXPR, init,
2895				       tf_warning_or_error);
2896	  /* Simplify for the case that we have an init containing the temp
2897	     alone.  */
2898	  if (t == n->init && n->var == NULL_TREE)
2899	    {
2900	      n->var = var;
2901	      proxy_replace pr = {TREE_OPERAND (t, 0), var};
2902	      cp_walk_tree (&init, replace_proxy, &pr, NULL);
2903	      n->init = init;
2904	      if (replace_in)
2905		cp_walk_tree (replace_in, replace_proxy, &pr, NULL);
2906	      flatten_await_stmt (n, promoted, temps_used, NULL);
2907	    }
2908	  else
2909	    {
2910	      var_nest_node *ins
2911		= new var_nest_node (var, init, n->prev, n);
2912	      /* We have to replace the target expr... */
2913	      *v.entry = var;
2914	      /* ... and any uses of its var.  */
2915	      proxy_replace pr = {TREE_OPERAND (t, 0), var};
2916	      cp_walk_tree (&n->init, replace_proxy, &pr, NULL);
2917	      /* Compiler-generated temporaries can also have uses in
2918		 following arms of compound expressions, which will be listed
2919		 in 'replace_in' if present.  */
2920	      if (replace_in)
2921		cp_walk_tree (replace_in, replace_proxy, &pr, NULL);
2922	      flatten_await_stmt (ins, promoted, temps_used, NULL);
2923	      flatten_await_stmt (n, promoted, temps_used, NULL);
2924	    }
2925	  return;
2926	}
2927	break;
2928    }
2929}
2930
2931/* Helper for 'process_conditional' that handles recursion into nested
2932   conditionals.  */
2933
2934static void
2935handle_nested_conditionals (var_nest_node *n, vec<tree>& list,
2936			    hash_map<tree, tree>& map)
2937{
2938  do
2939    {
2940      if (n->var && DECL_NAME (n->var))
2941	{
2942	  list.safe_push (n->var);
2943	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (n->var)))
2944	    {
2945	      bool existed;
2946	      tree& flag = map.get_or_insert (n->var, &existed);
2947	      if (!existed)
2948		{
2949		  /* We didn't see this var before and it needs a DTOR, so
2950		     build a guard variable for it.  */
2951		  char *nam
2952		    = xasprintf ("%s_guard",
2953				 IDENTIFIER_POINTER (DECL_NAME (n->var)));
2954		  flag = build_lang_decl (VAR_DECL, get_identifier (nam),
2955					  boolean_type_node);
2956		  free (nam);
2957		  DECL_ARTIFICIAL (flag) = true;
2958		}
2959
2960	      /* The initializer for this variable is replaced by a compound
2961		 expression that performs the init and then records that the
2962		 variable is live (and the DTOR should be run at the scope
2963		 exit.  */
2964	      tree set_flag = build2 (INIT_EXPR, boolean_type_node,
2965				      flag, boolean_true_node);
2966	      n->init
2967		= build2 (COMPOUND_EXPR, boolean_type_node, n->init, set_flag);
2968	}
2969	}
2970      if (TREE_CODE (n->init) == COND_EXPR)
2971	{
2972	  tree new_then = push_stmt_list ();
2973	  handle_nested_conditionals (n->then_cl, list, map);
2974	  new_then = pop_stmt_list (new_then);
2975	  tree new_else = push_stmt_list ();
2976	  handle_nested_conditionals (n->else_cl, list, map);
2977	  new_else = pop_stmt_list (new_else);
2978	  tree new_if
2979	    = build4 (IF_STMT, void_type_node, COND_EXPR_COND (n->init),
2980		      new_then, new_else, NULL_TREE);
2981	  add_stmt (new_if);
2982	}
2983      else
2984	finish_expr_stmt (n->init);
2985      n = n->next;
2986    } while (n);
2987}
2988
2989/* helper for 'maybe_promote_temps'.
2990
2991   When we have a conditional expression which might embed await expressions
2992   and/or promoted variables, we need to handle it appropriately.
2993
2994   The linked lists for the 'then' and 'else' clauses in a conditional node
2995   identify the promoted variables (but these cannot be wrapped in a regular
2996   cleanup).
2997
2998   So recurse through the lists and build up a composite list of captured vars.
2999   Declare these and any guard variables needed to decide if a DTOR should be
3000   run.  Then embed the conditional into a try-finally expression that handles
3001   running each DTOR conditionally on its guard variable.  */
3002
3003static void
3004process_conditional (var_nest_node *n, tree& vlist)
3005{
3006  tree init = n->init;
3007  hash_map<tree, tree> var_flags;
3008  auto_vec<tree> var_list;
3009  tree new_then = push_stmt_list ();
3010  handle_nested_conditionals (n->then_cl, var_list, var_flags);
3011  new_then = pop_stmt_list (new_then);
3012  tree new_else = push_stmt_list ();
3013  handle_nested_conditionals (n->else_cl, var_list, var_flags);
3014  new_else = pop_stmt_list (new_else);
3015  /* Declare the vars.  There are two loops so that the boolean flags are
3016     grouped in the frame.  */
3017  for (unsigned i = 0; i < var_list.length(); i++)
3018    {
3019      tree var = var_list[i];
3020      DECL_CHAIN (var) = vlist;
3021      vlist = var;
3022      add_decl_expr (var);
3023    }
3024  /* Define the guard flags for variables that need a DTOR.  */
3025  for (unsigned i = 0; i < var_list.length(); i++)
3026    {
3027      tree *flag = var_flags.get (var_list[i]);
3028      if (flag)
3029	{
3030	  DECL_INITIAL (*flag) = boolean_false_node;
3031	  DECL_CHAIN (*flag) = vlist;
3032	  vlist = *flag;
3033	  add_decl_expr (*flag);
3034	}
3035    }
3036  tree new_if
3037    = build4 (IF_STMT, void_type_node, COND_EXPR_COND (init),
3038	      new_then, new_else, NULL_TREE);
3039  /* Build a set of conditional DTORs.  */
3040  tree final_actions = push_stmt_list ();
3041  while (!var_list.is_empty())
3042    {
3043      tree var = var_list.pop ();
3044      tree *flag = var_flags.get (var);
3045      if (!flag)
3046	continue;
3047      tree var_type = TREE_TYPE (var);
3048      tree cleanup
3049	= build_special_member_call (var, complete_dtor_identifier,
3050				     NULL, var_type, LOOKUP_NORMAL,
3051				     tf_warning_or_error);
3052      tree cond_cleanup = begin_if_stmt ();
3053      finish_if_stmt_cond (*flag, cond_cleanup);
3054      finish_expr_stmt (cleanup);
3055      finish_then_clause (cond_cleanup);
3056      finish_if_stmt (cond_cleanup);
3057    }
3058  final_actions = pop_stmt_list (final_actions);
3059  tree try_finally
3060    = build2 (TRY_FINALLY_EXPR, void_type_node, new_if, final_actions);
3061  add_stmt (try_finally);
3062}
3063
3064/* Given *STMT, that contains at least one await expression.
3065
3066   The full expression represented in the original source code will contain
3067   suspension points, but it is still required that the lifetime of temporary
3068   values extends to the end of the expression.
3069
3070   We already have a mechanism to 'promote' user-authored local variables
3071   to a coroutine frame counterpart (which allows explicit management of the
3072   lifetime across suspensions).  The transform here re-writes STMT into
3073   a bind expression, promotes temporary values into local variables in that
3074   and flattens the statement into a series of cleanups.
3075
3076   Conditional expressions are re-written to regular 'if' statements.
3077   The cleanups for variables initialized inside a conditional (including
3078   nested cases) are wrapped in a try-finally clause, with guard variables
3079   to determine which DTORs need to be run.  */
3080
3081static tree
3082maybe_promote_temps (tree *stmt, void *d)
3083{
3084  susp_frame_data *awpts = (susp_frame_data *) d;
3085
3086  location_t sloc = EXPR_LOCATION (*stmt);
3087  tree expr = *stmt;
3088  /* Strip off uninteresting wrappers.  */
3089  if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
3090    expr = TREE_OPERAND (expr, 0);
3091  if (TREE_CODE (expr) == EXPR_STMT)
3092    expr = EXPR_STMT_EXPR (expr);
3093  if (TREE_CODE (expr) == CONVERT_EXPR
3094      && VOID_TYPE_P (TREE_TYPE (expr)))
3095    expr = TREE_OPERAND (expr, 0);
3096  STRIP_NOPS (expr);
3097
3098  /* We walk the statement trees, flattening it into an ordered list of
3099     variables with initializers and fragments corresponding to compound
3100     expressions, truth or/and if and ternary conditionals.  Conditional
3101     expressions carry a nested list of fragments for the then and else
3102     clauses.  We anchor to the 'bottom' of the fragment list; we will write
3103     a cleanup nest with one shell for each variable initialized.  */
3104  var_nest_node *root = new var_nest_node (NULL_TREE, expr, NULL, NULL);
3105  /* Check to see we didn't promote one twice.  */
3106  hash_set<tree> promoted_vars;
3107  hash_set<tree> used_temps;
3108  flatten_await_stmt (root, &promoted_vars, &used_temps, NULL);
3109
3110  gcc_checking_assert (root->next == NULL);
3111  tree vlist = NULL_TREE;
3112  var_nest_node *t = root;
3113  /* We build the bind scope expression from the bottom-up.
3114     EXPR_LIST holds the inner expression nest at the current cleanup
3115     level (becoming the final expression list when we've exhausted the
3116     number of sub-expression fragments).  */
3117  tree expr_list = NULL_TREE;
3118  do
3119    {
3120      tree new_list = push_stmt_list ();
3121      /* When we have a promoted variable, then add that to the bind scope
3122	 and initialize it.  When there's no promoted variable, we just need
3123	 to run the initializer.
3124	 If the initializer is a conditional expression, we need to collect
3125	 and declare any promoted variables nested within it.  DTORs for such
3126	 variables must be run conditionally too.  */
3127      if (t->var)
3128	{
3129	  tree var = t->var;
3130	  DECL_CHAIN (var) = vlist;
3131	  vlist = var;
3132	  add_decl_expr (var);
3133	  if (TREE_CODE (t->init) == COND_EXPR)
3134	    process_conditional (t, vlist);
3135	  else
3136	    finish_expr_stmt (t->init);
3137	  tree var_type = TREE_TYPE (var);
3138	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (var_type))
3139	    {
3140	      tree cleanup
3141		= build_special_member_call (var, complete_dtor_identifier,
3142					     NULL, var_type, LOOKUP_NORMAL,
3143					     tf_warning_or_error);
3144	      tree cl = build_stmt (sloc, CLEANUP_STMT, expr_list, cleanup, var);
3145	      add_stmt (cl); /* push this onto the level above.  */
3146	    }
3147	  else if (expr_list)
3148	    {
3149	      if (TREE_CODE (expr_list) != STATEMENT_LIST)
3150		add_stmt (expr_list);
3151	      else if (!tsi_end_p (tsi_start (expr_list)))
3152		add_stmt (expr_list);
3153	    }
3154	}
3155      else
3156	{
3157	  if (TREE_CODE (t->init) == COND_EXPR)
3158	    process_conditional (t, vlist);
3159	  else
3160	    finish_expr_stmt (t->init);
3161	  if (expr_list)
3162	    {
3163	      if (TREE_CODE (expr_list) != STATEMENT_LIST)
3164		add_stmt (expr_list);
3165	      else if (!tsi_end_p (tsi_start (expr_list)))
3166		add_stmt (expr_list);
3167	    }
3168	}
3169      expr_list = pop_stmt_list (new_list);
3170      var_nest_node *old = t;
3171      t = t->prev;
3172      delete old;
3173    } while (t);
3174
3175  /* Now produce the bind expression containing the 'promoted' temporaries
3176     as its variable list, and the cleanup nest as the statement.  */
3177  tree await_bind = build3_loc (sloc, BIND_EXPR, void_type_node,
3178				NULL, NULL, NULL);
3179  BIND_EXPR_BODY (await_bind) = expr_list;
3180  BIND_EXPR_VARS (await_bind) = nreverse (vlist);
3181  tree b_block = make_node (BLOCK);
3182  if (!awpts->block_stack->is_empty ())
3183    {
3184      tree s_block = awpts->block_stack->last ();
3185      if (s_block)
3186	{
3187	BLOCK_SUPERCONTEXT (b_block) = s_block;
3188	BLOCK_CHAIN (b_block) = BLOCK_SUBBLOCKS (s_block);
3189	BLOCK_SUBBLOCKS (s_block) = b_block;
3190	}
3191    }
3192  BLOCK_VARS (b_block) = BIND_EXPR_VARS (await_bind) ;
3193  BIND_EXPR_BLOCK (await_bind) = b_block;
3194  TREE_SIDE_EFFECTS (await_bind) = TREE_SIDE_EFFECTS (BIND_EXPR_BODY (await_bind));
3195  *stmt = await_bind;
3196  hash_set<tree> visited;
3197  return cp_walk_tree (stmt, register_awaits, d, &visited);
3198}
3199
3200/* Lightweight callback to determine two key factors:
3201   1) If the statement/expression contains any await expressions.
3202   2) If the statement/expression potentially requires a re-write to handle
3203      TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion
3204      so that the await expressions are not processed in the case of the
3205      short-circuit arm.
3206
3207   CO_YIELD expressions are re-written to their underlying co_await.  */
3208
3209static tree
3210analyze_expression_awaits (tree *stmt, int *do_subtree, void *d)
3211{
3212  susp_frame_data *awpts = (susp_frame_data *) d;
3213
3214  switch (TREE_CODE (*stmt))
3215    {
3216      default: return NULL_TREE;
3217      case CO_YIELD_EXPR:
3218	/* co_yield is syntactic sugar, re-write it to co_await.  */
3219	*stmt = TREE_OPERAND (*stmt, 1);
3220	/* FALLTHROUGH */
3221      case CO_AWAIT_EXPR:
3222	awpts->saw_awaits++;
3223	/* A non-null initializer for the awaiter means we need to expand.  */
3224	if (TREE_OPERAND (*stmt, 2))
3225	  awpts->has_awaiter_init = true;
3226	break;
3227      case TRUTH_ANDIF_EXPR:
3228      case TRUTH_ORIF_EXPR:
3229	{
3230	  /* We don't need special action for awaits in the always-executed
3231	     arm of a TRUTH_IF.  */
3232	  if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 0),
3233				       analyze_expression_awaits, d, NULL))
3234	    return res;
3235	  /* However, if there are await expressions on the conditionally
3236	     executed branch, we must expand the TRUTH_IF to ensure that the
3237	     expanded await expression control-flow is fully contained in the
3238	     conditionally executed code.  */
3239	  unsigned aw_count = awpts->saw_awaits;
3240	  if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 1),
3241				       analyze_expression_awaits, d, NULL))
3242	    return res;
3243	  if (awpts->saw_awaits > aw_count)
3244	    {
3245	      awpts->truth_aoif_to_expand->add (*stmt);
3246	      awpts->needs_truth_if_exp = true;
3247	    }
3248	  /* We've done the sub-trees here.  */
3249	  *do_subtree = 0;
3250	}
3251	break;
3252    }
3253
3254  return NULL_TREE; /* Recurse until done.  */
3255}
3256
3257/* Given *EXPR
3258   If EXPR contains a TRUTH_{AND,OR}IF_EXPR, TAOIE with an await expr on
3259   the conditionally executed branch, change this in a ternary operator.
3260
3261   bool not_expr = TAOIE == TRUTH_ORIF_EXPR ? NOT : NOP;
3262   not_expr (always-exec expr) ? conditionally-exec expr : not_expr;
3263
3264   Apply this recursively to the condition and the conditionally-exec
3265   branch.  */
3266
3267struct truth_if_transform {
3268  tree *orig_stmt;
3269  tree scratch_var;
3270  hash_set<tree> *truth_aoif_to_expand;
3271};
3272
3273static tree
3274expand_one_truth_if (tree *expr, int *do_subtree, void *d)
3275{
3276  truth_if_transform *xform = (truth_if_transform *) d;
3277
3278  bool needs_not = false;
3279  switch (TREE_CODE (*expr))
3280    {
3281      default: break;
3282      case TRUTH_ORIF_EXPR:
3283	needs_not = true;
3284	/* FALLTHROUGH */
3285      case TRUTH_ANDIF_EXPR:
3286	{
3287	  if (!xform->truth_aoif_to_expand->contains (*expr))
3288	    break;
3289
3290	  location_t sloc = EXPR_LOCATION (*expr);
3291	  /* Transform truth expression into a cond expression with
3292	     * the always-executed arm as the condition.
3293	     * the conditionally-executed arm as the then clause.
3294	     * the 'else' clause is fixed: 'true' for ||,'false' for &&.  */
3295	  tree cond = TREE_OPERAND (*expr, 0);
3296	  tree test1 = TREE_OPERAND (*expr, 1);
3297	  tree fixed = needs_not ? boolean_true_node : boolean_false_node;
3298	  if (needs_not)
3299	    cond = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
3300	  tree cond_expr
3301	    = build3_loc (sloc, COND_EXPR, boolean_type_node,
3302			  cond, test1, fixed);
3303	  *expr = cond_expr;
3304	  if (tree res = cp_walk_tree (&COND_EXPR_COND (*expr),
3305				       expand_one_truth_if, d, NULL))
3306	    return res;
3307	  if (tree res = cp_walk_tree (&COND_EXPR_THEN (*expr),
3308				       expand_one_truth_if, d, NULL))
3309	    return res;
3310	  /* We've manually processed necessary sub-trees here.  */
3311	  *do_subtree = 0;
3312	}
3313	break;
3314    }
3315  return NULL_TREE;
3316}
3317
3318/* Helper that adds a new variable of VAR_TYPE to a bind scope BIND, the
3319   name is made up from NAM_ROOT, NAM_VERS.  */
3320
3321static tree
3322add_var_to_bind (tree& bind, tree var_type,
3323		 const char *nam_root, unsigned nam_vers)
3324{
3325  tree b_vars = BIND_EXPR_VARS (bind);
3326  /* Build a variable to hold the condition, this will be included in the
3327     frame as a local var.  */
3328  char *nam = xasprintf ("__%s_%d", nam_root, nam_vers);
3329  tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
3330  free (nam);
3331  DECL_CHAIN (newvar) = b_vars;
3332  BIND_EXPR_VARS (bind) = newvar;
3333  return newvar;
3334}
3335
3336/* Helper to build and add if (!cond) break;  */
3337
3338static void
3339coro_build_add_if_not_cond_break (tree cond)
3340{
3341  tree if_stmt = begin_if_stmt ();
3342  tree invert = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
3343  finish_if_stmt_cond (invert, if_stmt);
3344  finish_break_stmt ();
3345  finish_then_clause (if_stmt);
3346  finish_if_stmt (if_stmt);
3347}
3348
3349/* Tree walk callback to replace continue statements with goto label.  */
3350static tree
3351replace_continue (tree *stmt, int *do_subtree, void *d)
3352{
3353  tree expr = *stmt;
3354  if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
3355    expr = TREE_OPERAND (expr, 0);
3356  if (CONVERT_EXPR_P (expr) && VOID_TYPE_P (expr))
3357    expr = TREE_OPERAND (expr, 0);
3358  STRIP_NOPS (expr);
3359  if (!STATEMENT_CLASS_P (expr))
3360    return NULL_TREE;
3361
3362  switch (TREE_CODE (expr))
3363    {
3364      /* Unless it's a special case, just walk the subtrees as usual.  */
3365      default: return NULL_TREE;
3366
3367      case CONTINUE_STMT:
3368	{
3369	  tree *label = (tree *)d;
3370	  location_t loc = EXPR_LOCATION (expr);
3371	  /* re-write a continue to goto label.  */
3372	  *stmt = build_stmt (loc, GOTO_EXPR, *label);
3373	  *do_subtree = 0;
3374	  return NULL_TREE;
3375	}
3376
3377      /* Statements that do not require recursion.  */
3378      case DECL_EXPR:
3379      case BREAK_STMT:
3380      case GOTO_EXPR:
3381      case LABEL_EXPR:
3382      case CASE_LABEL_EXPR:
3383      case ASM_EXPR:
3384      /* These must break recursion.  */
3385      case FOR_STMT:
3386      case WHILE_STMT:
3387      case DO_STMT:
3388	*do_subtree = 0;
3389	return NULL_TREE;
3390    }
3391}
3392
3393/* Tree walk callback to analyze, register and pre-process statements that
3394   contain await expressions.  */
3395
3396static tree
3397await_statement_walker (tree *stmt, int *do_subtree, void *d)
3398{
3399  tree res = NULL_TREE;
3400  susp_frame_data *awpts = (susp_frame_data *) d;
3401
3402  /* Process a statement at a time.  */
3403  if (TREE_CODE (*stmt) == BIND_EXPR)
3404    {
3405      /* For conditional expressions, we might wish to add an artificial var
3406	 to their containing bind expr.  */
3407      vec_safe_push (awpts->bind_stack, *stmt);
3408      /* We might need to insert a new bind expression, and want to link it
3409	 into the correct scope, so keep a note of the current block scope.  */
3410      tree blk = BIND_EXPR_BLOCK (*stmt);
3411      vec_safe_push (awpts->block_stack, blk);
3412      res = cp_walk_tree (&BIND_EXPR_BODY (*stmt), await_statement_walker,
3413			  d, NULL);
3414      awpts->block_stack->pop ();
3415      awpts->bind_stack->pop ();
3416      *do_subtree = 0; /* Done subtrees.  */
3417      return res;
3418    }
3419  else if (TREE_CODE (*stmt) == STATEMENT_LIST)
3420    {
3421      for (tree &s : tsi_range (*stmt))
3422	{
3423	  res = cp_walk_tree (&s, await_statement_walker,
3424			      d, NULL);
3425	  if (res)
3426	    return res;
3427	}
3428      *do_subtree = 0; /* Done subtrees.  */
3429      return NULL_TREE;
3430    }
3431
3432  /* We have something to be handled as a single statement.  We have to handle
3433     a few statements specially where await statements have to be moved out of
3434     constructs.  */
3435  tree expr = *stmt;
3436  if (TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
3437    expr = TREE_OPERAND (expr, 0);
3438  STRIP_NOPS (expr);
3439
3440  if (STATEMENT_CLASS_P (expr))
3441    switch (TREE_CODE (expr))
3442      {
3443	/* Unless it's a special case, just walk the subtrees as usual.  */
3444	default: return NULL_TREE;
3445
3446	/* When we have a conditional expression, which contains one or more
3447	   await expressions, we have to break the condition out into a
3448	   regular statement so that the control flow introduced by the await
3449	   transforms can be implemented.  */
3450	case IF_STMT:
3451	  {
3452	    tree *await_ptr;
3453	    hash_set<tree> visited;
3454	    /* Transform 'if (cond with awaits) then stmt1 else stmt2' into
3455	       bool cond = cond with awaits.
3456	       if (cond) then stmt1 else stmt2.  */
3457	    tree if_stmt = *stmt;
3458	    /* We treat the condition as if it was a stand-alone statement,
3459	       to see if there are any await expressions which will be analyzed
3460	       and registered.  */
3461	    if (!(cp_walk_tree (&IF_COND (if_stmt),
3462		  find_any_await, &await_ptr, &visited)))
3463	      return NULL_TREE; /* Nothing special to do here.  */
3464
3465	    gcc_checking_assert (!awpts->bind_stack->is_empty());
3466	    tree& bind_expr = awpts->bind_stack->last ();
3467	    tree newvar = add_var_to_bind (bind_expr, boolean_type_node,
3468					   "ifcd", awpts->cond_number++);
3469	    tree insert_list = push_stmt_list ();
3470	    tree cond_inner = IF_COND (if_stmt);
3471	    if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
3472	      cond_inner = TREE_OPERAND (cond_inner, 0);
3473	    add_decl_expr (newvar);
3474	    location_t sloc = EXPR_LOCATION (IF_COND (if_stmt));
3475	    /* We want to initialize the new variable with the expression
3476	       that contains the await(s) and potentially also needs to
3477	       have truth_if expressions expanded.  */
3478	    tree new_s = build2_loc (sloc, INIT_EXPR, boolean_type_node,
3479				     newvar, cond_inner);
3480	    finish_expr_stmt (new_s);
3481	    IF_COND (if_stmt) = newvar;
3482	    add_stmt (if_stmt);
3483	    *stmt = pop_stmt_list (insert_list);
3484	    /* So now walk the new statement list.  */
3485	    res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
3486	    *do_subtree = 0; /* Done subtrees.  */
3487	    return res;
3488	  }
3489	  break;
3490	case FOR_STMT:
3491	  {
3492	    tree *await_ptr;
3493	    hash_set<tree> visited;
3494	    /* for loops only need special treatment if the condition or the
3495	       iteration expression contain a co_await.  */
3496	    tree for_stmt = *stmt;
3497	    /* At present, the FE always generates a separate initializer for
3498	       the FOR_INIT_STMT, when the expression has an await.  Check that
3499	       this assumption holds in the future. */
3500	    gcc_checking_assert
3501	      (!(cp_walk_tree (&FOR_INIT_STMT (for_stmt), find_any_await,
3502			       &await_ptr, &visited)));
3503
3504	    visited.empty ();
3505	    bool for_cond_await
3506	      = cp_walk_tree (&FOR_COND (for_stmt), find_any_await,
3507			      &await_ptr, &visited);
3508
3509	    visited.empty ();
3510	    bool for_expr_await
3511	      = cp_walk_tree (&FOR_EXPR (for_stmt), find_any_await,
3512			      &await_ptr, &visited);
3513
3514	    /* If the condition has an await, then we will need to rewrite the
3515	       loop as
3516	       for (init expression;true;iteration expression) {
3517		  condition = await expression;
3518		  if (condition)
3519		    break;
3520		  ...
3521		}
3522	    */
3523	    if (for_cond_await)
3524	      {
3525		tree insert_list = push_stmt_list ();
3526		/* This will be expanded when the revised body is handled.  */
3527		coro_build_add_if_not_cond_break (FOR_COND (for_stmt));
3528		/* .. add the original for body.  */
3529		add_stmt (FOR_BODY (for_stmt));
3530		/* To make the new for body.  */
3531		FOR_BODY (for_stmt) = pop_stmt_list (insert_list);
3532		FOR_COND (for_stmt) = boolean_true_node;
3533	      }
3534	    /* If the iteration expression has an await, it's a bit more
3535	       tricky.
3536	       for (init expression;condition;) {
3537		 ...
3538		 iteration_expr_label:
3539		   iteration expression with await;
3540	       }
3541	       but, then we will need to re-write any continue statements into
3542	       'goto iteration_expr_label:'.
3543	    */
3544	    if (for_expr_await)
3545	      {
3546		location_t sloc = EXPR_LOCATION (FOR_EXPR (for_stmt));
3547		tree insert_list = push_stmt_list ();
3548		/* The original for body.  */
3549		add_stmt (FOR_BODY (for_stmt));
3550		char *buf = xasprintf ("for.iter.expr.%u", awpts->cond_number++);
3551		tree it_expr_label
3552		  = create_named_label_with_ctx (sloc, buf, NULL_TREE);
3553		free (buf);
3554		add_stmt (build_stmt (sloc, LABEL_EXPR, it_expr_label));
3555		tree for_expr = FOR_EXPR (for_stmt);
3556		/* Present the iteration expression as a statement.  */
3557		if (TREE_CODE (for_expr) == CLEANUP_POINT_EXPR)
3558		  for_expr = TREE_OPERAND (for_expr, 0);
3559		STRIP_NOPS (for_expr);
3560		finish_expr_stmt (for_expr);
3561		FOR_EXPR (for_stmt) = NULL_TREE;
3562		FOR_BODY (for_stmt) = pop_stmt_list (insert_list);
3563		/* rewrite continue statements to goto label.  */
3564		hash_set<tree> visited_continue;
3565		if ((res = cp_walk_tree (&FOR_BODY (for_stmt),
3566		     replace_continue, &it_expr_label, &visited_continue)))
3567		  return res;
3568	      }
3569
3570	    /* So now walk the body statement (list), if there were no await
3571	       expressions, then this handles the original body - and either
3572	       way we will have finished with this statement.  */
3573	    res = cp_walk_tree (&FOR_BODY (for_stmt),
3574				await_statement_walker, d, NULL);
3575	    *do_subtree = 0; /* Done subtrees.  */
3576	    return res;
3577	  }
3578	  break;
3579	case WHILE_STMT:
3580	  {
3581	    /* We turn 'while (cond with awaits) stmt' into
3582	       while (true) {
3583		  if (!(cond with awaits))
3584		    break;
3585		  stmt..
3586		} */
3587	    tree *await_ptr;
3588	    hash_set<tree> visited;
3589	    tree while_stmt = *stmt;
3590	    if (!(cp_walk_tree (&WHILE_COND (while_stmt),
3591		  find_any_await, &await_ptr, &visited)))
3592	      return NULL_TREE; /* Nothing special to do here.  */
3593
3594	    tree insert_list = push_stmt_list ();
3595	    coro_build_add_if_not_cond_break (WHILE_COND (while_stmt));
3596	    /* The original while body.  */
3597	    add_stmt (WHILE_BODY (while_stmt));
3598	    /* The new while body.  */
3599	    WHILE_BODY (while_stmt) = pop_stmt_list (insert_list);
3600	    WHILE_COND (while_stmt) = boolean_true_node;
3601	    /* So now walk the new statement list.  */
3602	    res = cp_walk_tree (&WHILE_BODY (while_stmt),
3603				await_statement_walker, d, NULL);
3604	    *do_subtree = 0; /* Done subtrees.  */
3605	    return res;
3606	  }
3607	  break;
3608	case DO_STMT:
3609	  {
3610	    /* We turn do stmt while (cond with awaits) into:
3611	       do {
3612		  stmt..
3613		  if (!(cond with awaits))
3614		    break;
3615	       } while (true); */
3616	    tree do_stmt = *stmt;
3617	    tree *await_ptr;
3618	    hash_set<tree> visited;
3619	    if (!(cp_walk_tree (&DO_COND (do_stmt),
3620		  find_any_await, &await_ptr, &visited)))
3621	      return NULL_TREE; /* Nothing special to do here.  */
3622
3623	    tree insert_list = push_stmt_list ();
3624	    /* The original do stmt body.  */
3625	    add_stmt (DO_BODY (do_stmt));
3626	    coro_build_add_if_not_cond_break (DO_COND (do_stmt));
3627	    /* The new while body.  */
3628	    DO_BODY (do_stmt) = pop_stmt_list (insert_list);
3629	    DO_COND (do_stmt) = boolean_true_node;
3630	    /* So now walk the new statement list.  */
3631	    res = cp_walk_tree (&DO_BODY (do_stmt), await_statement_walker,
3632				d, NULL);
3633	    *do_subtree = 0; /* Done subtrees.  */
3634	    return res;
3635	  }
3636	  break;
3637	case SWITCH_STMT:
3638	  {
3639	    /* We turn 'switch (cond with awaits) stmt' into
3640	       switch_type cond = cond with awaits
3641	       switch (cond) stmt.  */
3642	    tree sw_stmt = *stmt;
3643	    tree *await_ptr;
3644	    hash_set<tree> visited;
3645	    if (!(cp_walk_tree (&SWITCH_STMT_COND (sw_stmt),
3646		  find_any_await, &await_ptr, &visited)))
3647	      return NULL_TREE; /* Nothing special to do here.  */
3648
3649	    gcc_checking_assert (!awpts->bind_stack->is_empty());
3650	    /* Build a variable to hold the condition, this will be
3651		   included in the frame as a local var.  */
3652	    tree& bind_expr = awpts->bind_stack->last ();
3653	    tree sw_type = SWITCH_STMT_TYPE (sw_stmt);
3654	    tree newvar = add_var_to_bind (bind_expr, sw_type, "swch",
3655					   awpts->cond_number++);
3656	    tree insert_list = push_stmt_list ();
3657	    add_decl_expr (newvar);
3658
3659	    tree cond_inner = SWITCH_STMT_COND (sw_stmt);
3660	    if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
3661	      cond_inner = TREE_OPERAND (cond_inner, 0);
3662	    location_t sloc = EXPR_LOCATION (SWITCH_STMT_COND (sw_stmt));
3663	    tree new_s = build2_loc (sloc, INIT_EXPR, sw_type, newvar,
3664				     cond_inner);
3665	    finish_expr_stmt (new_s);
3666	    SWITCH_STMT_COND (sw_stmt) = newvar;
3667	    /* Now add the switch statement with the condition re-
3668		   written to use the local var.  */
3669	    add_stmt (sw_stmt);
3670	    *stmt = pop_stmt_list (insert_list);
3671	    /* Process the expanded list.  */
3672	    res = cp_walk_tree (stmt, await_statement_walker,
3673				d, NULL);
3674	    *do_subtree = 0; /* Done subtrees.  */
3675	    return res;
3676	  }
3677	  break;
3678	case CO_RETURN_EXPR:
3679	  {
3680	    /* Expand the co_return as per [stmt.return.coroutine]
3681	       - for co_return;
3682		{ p.return_void (); goto final_suspend; }
3683	       - for co_return [void expr];
3684		{ expr; p.return_void(); goto final_suspend;}
3685	       - for co_return [non void expr];
3686		{ p.return_value(expr); goto final_suspend; }  */
3687	    location_t loc = EXPR_LOCATION (expr);
3688	    tree call = TREE_OPERAND (expr, 1);
3689	    expr = TREE_OPERAND (expr, 0);
3690	    tree ret_list = push_stmt_list ();
3691	    /* [stmt.return.coroutine], 2.2
3692	       If expr is present and void, it is placed immediately before
3693	       the call for return_void;  */
3694	    if (expr && VOID_TYPE_P (TREE_TYPE (expr)))
3695	      finish_expr_stmt (expr);
3696	    /* Insert p.return_{void,value(expr)}.  */
3697	    finish_expr_stmt (call);
3698	    TREE_USED (awpts->fs_label) = 1;
3699	    add_stmt (build_stmt (loc, GOTO_EXPR, awpts->fs_label));
3700	    *stmt = pop_stmt_list (ret_list);
3701	    res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
3702	    /* Once this is complete, we will have processed subtrees.  */
3703	    *do_subtree = 0;
3704	    return res;
3705	  }
3706	  break;
3707	case HANDLER:
3708	  {
3709	    /* [expr.await] An await-expression shall appear only in a
3710	       potentially-evaluated expression within the compound-statement
3711	       of a function-body outside of a handler.  */
3712	    tree *await_ptr;
3713	    hash_set<tree> visited;
3714	    if (!(cp_walk_tree (&HANDLER_BODY (expr), find_any_await,
3715		  &await_ptr, &visited)))
3716	      return NULL_TREE; /* All OK.  */
3717	    location_t loc = EXPR_LOCATION (*await_ptr);
3718	    error_at (loc, "await expressions are not permitted in handlers");
3719	    return NULL_TREE; /* This is going to fail later anyway.  */
3720	  }
3721	  break;
3722      }
3723  else if (EXPR_P (expr))
3724    {
3725      hash_set<tree> visited;
3726      tree *await_ptr;
3727      if (!(cp_walk_tree (stmt, find_any_await, &await_ptr, &visited)))
3728	return NULL_TREE; /* Nothing special to do here.  */
3729
3730      visited.empty ();
3731      awpts->saw_awaits = 0;
3732      hash_set<tree> truth_aoif_to_expand;
3733      awpts->truth_aoif_to_expand = &truth_aoif_to_expand;
3734      awpts->needs_truth_if_exp = false;
3735      awpts->has_awaiter_init = false;
3736      if ((res = cp_walk_tree (stmt, analyze_expression_awaits, d, &visited)))
3737	return res;
3738      *do_subtree = 0; /* Done subtrees.  */
3739      if (!awpts->saw_awaits)
3740	return NULL_TREE; /* Nothing special to do here.  */
3741
3742      if (awpts->needs_truth_if_exp)
3743	{
3744	  /* If a truth-and/or-if expression has an await expression in the
3745	     conditionally-taken branch, then it must be rewritten into a
3746	     regular conditional.  */
3747	  truth_if_transform xf = {stmt, NULL_TREE, &truth_aoif_to_expand};
3748	  if ((res = cp_walk_tree (stmt, expand_one_truth_if, &xf, NULL)))
3749	    return res;
3750	}
3751      /* Process this statement, which contains at least one await expression
3752	 to 'promote' temporary values to a coroutine frame slot.  */
3753      return maybe_promote_temps (stmt, d);
3754    }
3755  /* Continue recursion, if needed.  */
3756  return res;
3757}
3758
3759/* For figuring out what param usage we have.  */
3760
3761struct param_frame_data
3762{
3763  tree *field_list;
3764  hash_map<tree, param_info> *param_uses;
3765  hash_set<tree *> *visited;
3766  location_t loc;
3767  bool param_seen;
3768};
3769
3770/* A tree walk callback that rewrites each parm use to the local variable
3771   that represents its copy in the frame.  */
3772
3773static tree
3774rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
3775{
3776  param_frame_data *data = (param_frame_data *) d;
3777
3778  /* For lambda closure content, we have to look specifically.  */
3779  if (TREE_CODE (*stmt) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*stmt))
3780    {
3781      tree t = DECL_VALUE_EXPR (*stmt);
3782      return cp_walk_tree (&t, rewrite_param_uses, d, NULL);
3783    }
3784
3785  if (TREE_CODE (*stmt) != PARM_DECL)
3786    return NULL_TREE;
3787
3788  /* If we already saw the containing expression, then we're done.  */
3789  if (data->visited->add (stmt))
3790    return NULL_TREE;
3791
3792  bool existed;
3793  param_info &parm = data->param_uses->get_or_insert (*stmt, &existed);
3794  gcc_checking_assert (existed);
3795
3796  *stmt = parm.copy_var;
3797  return NULL_TREE;
3798}
3799
3800/* Build up a set of info that determines how each param copy will be
3801   handled.  */
3802
3803static hash_map<tree, param_info> *
3804analyze_fn_parms (tree orig)
3805{
3806  if (!DECL_ARGUMENTS (orig))
3807    return NULL;
3808
3809  hash_map<tree, param_info> *param_uses = new hash_map<tree, param_info>;
3810
3811  /* Build a hash map with an entry for each param.
3812     The key is the param tree.
3813     Then we have an entry for the frame field name.
3814     Then a cache for the field ref when we come to use it.
3815     Then a tree list of the uses.
3816     The second two entries start out empty - and only get populated
3817     when we see uses.  */
3818  bool lambda_p = LAMBDA_FUNCTION_P (orig);
3819
3820  unsigned no_name_parm = 0;
3821  for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
3822    {
3823      bool existed;
3824      param_info &parm = param_uses->get_or_insert (arg, &existed);
3825      gcc_checking_assert (!existed);
3826      parm.body_uses = NULL;
3827      tree actual_type = TREE_TYPE (arg);
3828      actual_type = complete_type_or_else (actual_type, orig);
3829      if (actual_type == NULL_TREE)
3830	actual_type = error_mark_node;
3831      parm.orig_type = actual_type;
3832      parm.by_ref = parm.pt_ref = parm.rv_ref =  false;
3833      if (TREE_CODE (actual_type) == REFERENCE_TYPE)
3834	{
3835	  /* If the user passes by reference, then we will save the
3836	     pointer to the original.  As noted in
3837	     [dcl.fct.def.coroutine] / 13, if the lifetime of the
3838	     referenced item ends and then the coroutine is resumed,
3839	     we have UB; well, the user asked for it.  */
3840	  if (TYPE_REF_IS_RVALUE (actual_type))
3841		parm.rv_ref = true;
3842	  else
3843		parm.pt_ref = true;
3844	}
3845      else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
3846	parm.by_ref = true;
3847
3848      parm.frame_type = actual_type;
3849
3850      parm.this_ptr = is_this_parameter (arg);
3851      parm.lambda_cobj = lambda_p && DECL_NAME (arg) == closure_identifier;
3852
3853      tree name = DECL_NAME (arg);
3854      if (!name)
3855	{
3856	  char *buf = xasprintf ("_Coro_unnamed_parm_%d", no_name_parm++);
3857	  name = get_identifier (buf);
3858	  free (buf);
3859	}
3860      parm.field_id = name;
3861
3862      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (parm.frame_type))
3863	{
3864	  char *buf = xasprintf ("%s%s_live", DECL_NAME (arg) ? "_Coro_" : "",
3865				 IDENTIFIER_POINTER (name));
3866	  parm.guard_var
3867	    = coro_build_artificial_var (UNKNOWN_LOCATION, get_identifier (buf),
3868					 boolean_type_node, orig,
3869					 boolean_false_node);
3870	  free (buf);
3871	  parm.trivial_dtor = false;
3872	}
3873      else
3874	parm.trivial_dtor = true;
3875    }
3876
3877  return param_uses;
3878}
3879
3880/* Small helper for the repetitive task of adding a new field to the coro
3881   frame type.  */
3882
3883static tree
3884coro_make_frame_entry (tree *field_list, const char *name, tree fld_type,
3885		       location_t loc)
3886{
3887  tree id = get_identifier (name);
3888  tree decl = build_decl (loc, FIELD_DECL, id, fld_type);
3889  DECL_CHAIN (decl) = *field_list;
3890  *field_list = decl;
3891  return id;
3892}
3893
3894/* For recording local variable usage.  */
3895
3896struct local_vars_frame_data
3897{
3898  tree *field_list;
3899  hash_map<tree, local_var_info> *local_var_uses;
3900  unsigned int nest_depth, bind_indx;
3901  location_t loc;
3902  bool saw_capture;
3903  bool local_var_seen;
3904};
3905
3906/* A tree-walk callback that processes one bind expression noting local
3907   variables, and making a coroutine frame slot available for those that
3908   need it, so that they can be 'promoted' across suspension points.  */
3909
3910static tree
3911register_local_var_uses (tree *stmt, int *do_subtree, void *d)
3912{
3913  local_vars_frame_data *lvd = (local_vars_frame_data *) d;
3914
3915  /* As we enter a bind expression - record the vars there and then recurse.
3916     As we exit drop the nest depth.
3917     The bind index is a growing count of how many bind indices we've seen.
3918     We build a space in the frame for each local var.  */
3919
3920  if (TREE_CODE (*stmt) == BIND_EXPR)
3921    {
3922      tree lvar;
3923      unsigned serial = 0;
3924      for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
3925	   lvar = DECL_CHAIN (lvar))
3926	{
3927	  bool existed;
3928	  local_var_info &local_var
3929	    = lvd->local_var_uses->get_or_insert (lvar, &existed);
3930	  gcc_checking_assert (!existed);
3931	  local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
3932	  tree lvtype = TREE_TYPE (lvar);
3933	  local_var.frame_type = lvtype;
3934	  local_var.field_idx = local_var.field_id = NULL_TREE;
3935
3936	  /* Make sure that we only present vars to the tests below.  */
3937	  if (TREE_CODE (lvar) == TYPE_DECL
3938	      || TREE_CODE (lvar) == NAMESPACE_DECL)
3939	    continue;
3940
3941	  /* We don't move static vars into the frame. */
3942	  local_var.is_static = TREE_STATIC (lvar);
3943	  if (local_var.is_static)
3944	    continue;
3945
3946	  poly_uint64 size;
3947	  if (TREE_CODE (lvtype) == ARRAY_TYPE
3948	      && !poly_int_tree_p (DECL_SIZE_UNIT (lvar), &size))
3949	    {
3950	      sorry_at (local_var.def_loc, "variable length arrays are not"
3951			" yet supported in coroutines");
3952	      /* Ignore it, this is broken anyway.  */
3953	      continue;
3954	    }
3955
3956	  lvd->local_var_seen = true;
3957	  /* If this var is a lambda capture proxy, we want to leave it alone,
3958	     and later rewrite the DECL_VALUE_EXPR to indirect through the
3959	     frame copy of the pointer to the lambda closure object.  */
3960	  local_var.is_lambda_capture = is_capture_proxy (lvar);
3961	  if (local_var.is_lambda_capture)
3962	    continue;
3963
3964	  /* If a variable has a value expression, then that's what needs
3965	     to be processed.  */
3966	  local_var.has_value_expr_p = DECL_HAS_VALUE_EXPR_P (lvar);
3967	  if (local_var.has_value_expr_p)
3968	    continue;
3969
3970	  /* Make names depth+index unique, so that we can support nested
3971	     scopes with identically named locals and still be able to
3972	     identify them in the coroutine frame.  */
3973	  tree lvname = DECL_NAME (lvar);
3974	  char *buf = NULL;
3975
3976	  /* The outermost bind scope contains the artificial variables that
3977	     we inject to implement the coro state machine.  We want to be able
3978	     to inspect these in debugging.  */
3979	  if (lvname != NULL_TREE && lvd->nest_depth == 0)
3980	    buf = xasprintf ("%s", IDENTIFIER_POINTER (lvname));
3981	  else if (lvname != NULL_TREE)
3982	    buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname),
3983			     lvd->nest_depth, lvd->bind_indx);
3984	  else
3985	    buf = xasprintf ("_D%u_%u_%u", lvd->nest_depth, lvd->bind_indx,
3986			     serial++);
3987
3988	  /* TODO: Figure out if we should build a local type that has any
3989	     excess alignment or size from the original decl.  */
3990	  local_var.field_id = coro_make_frame_entry (lvd->field_list, buf,
3991						      lvtype, lvd->loc);
3992	  free (buf);
3993	  /* We don't walk any of the local var sub-trees, they won't contain
3994	     any bind exprs.  */
3995	}
3996      lvd->bind_indx++;
3997      lvd->nest_depth++;
3998      cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
3999      *do_subtree = 0; /* We've done this.  */
4000      lvd->nest_depth--;
4001    }
4002  return NULL_TREE;
4003}
4004
4005/* Build, return FUNCTION_DECL node based on ORIG with a type FN_TYPE which has
4006   a single argument of type CORO_FRAME_PTR.  Build the actor function if
4007   ACTOR_P is true, otherwise the destroy. */
4008
4009static tree
4010coro_build_actor_or_destroy_function (tree orig, tree fn_type,
4011				      tree coro_frame_ptr, bool actor_p)
4012{
4013  location_t loc = DECL_SOURCE_LOCATION (orig);
4014  tree fn
4015    = build_lang_decl (FUNCTION_DECL, copy_node (DECL_NAME (orig)), fn_type);
4016
4017  /* Allow for locating the ramp (original) function from this one.  */
4018  if (!to_ramp)
4019    to_ramp = hash_map<tree, tree>::create_ggc (10);
4020  to_ramp->put (fn, orig);
4021
4022  DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
4023  DECL_SOURCE_LOCATION (fn) = loc;
4024  DECL_ARTIFICIAL (fn) = true;
4025  DECL_INITIAL (fn) = error_mark_node;
4026
4027  tree id = get_identifier ("frame_ptr");
4028  tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
4029  DECL_CONTEXT (fp) = fn;
4030  DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
4031  DECL_ARGUMENTS (fn) = fp;
4032
4033  /* Copy selected attributes from the original function.  */
4034  TREE_USED (fn) = TREE_USED (orig);
4035  if (DECL_SECTION_NAME (orig))
4036    set_decl_section_name (fn, orig);
4037  /* Copy any alignment that the FE added.  */
4038  if (DECL_ALIGN (orig))
4039    SET_DECL_ALIGN (fn, DECL_ALIGN (orig));
4040  /* Copy any alignment the user added.  */
4041  DECL_USER_ALIGN (fn) = DECL_USER_ALIGN (orig);
4042  /* Apply attributes from the original fn.  */
4043  DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig));
4044
4045  /* A void return.  */
4046  tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
4047  DECL_CONTEXT (resdecl) = fn;
4048  DECL_ARTIFICIAL (resdecl) = 1;
4049  DECL_IGNORED_P (resdecl) = 1;
4050  DECL_RESULT (fn) = resdecl;
4051
4052  /* This is a coroutine component.  */
4053  DECL_COROUTINE_P (fn) = 1;
4054
4055  /* Set up a means to find out if a decl is one of the helpers and, if so,
4056     which one.  */
4057  if (coroutine_info *info = get_coroutine_info (orig))
4058    {
4059      gcc_checking_assert ((actor_p && info->actor_decl == NULL_TREE)
4060			   || info->destroy_decl == NULL_TREE);
4061      if (actor_p)
4062	info->actor_decl = fn;
4063      else
4064	info->destroy_decl = fn;
4065    }
4066  return fn;
4067}
4068
4069/* Re-write the body as per [dcl.fct.def.coroutine] / 5.  */
4070
4071static tree
4072coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig,
4073			    hash_map<tree, param_info> *param_uses,
4074			    tree resume_fn_ptr_type,
4075			    tree& resume_idx_var, tree& fs_label)
4076{
4077  /* This will be our new outer scope.  */
4078  tree update_body = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4079  tree top_block = make_node (BLOCK);
4080  BIND_EXPR_BLOCK (update_body) = top_block;
4081  BIND_EXPR_BODY (update_body) = push_stmt_list ();
4082
4083  /* If the function has a top level bind expression, then connect that
4084     after first making sure we give it a new block.  */
4085  tree first = expr_first (fnbody);
4086  if (first && TREE_CODE (first) == BIND_EXPR)
4087    {
4088      tree block = BIND_EXPR_BLOCK (first);
4089      gcc_checking_assert (block);
4090      gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
4091      gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE);
4092      /* Replace the top block to avoid issues with locations for args
4093	 appearing to be in a non-existent place.  */
4094      tree replace_blk = make_node (BLOCK);
4095      BLOCK_VARS (replace_blk) = BLOCK_VARS (block);
4096      BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block);
4097      for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b))
4098	BLOCK_SUPERCONTEXT (b) = replace_blk;
4099      BIND_EXPR_BLOCK (first) = replace_blk;
4100      /* The top block has one child, so far, and we have now got a
4101	 superblock.  */
4102      BLOCK_SUPERCONTEXT (replace_blk) = top_block;
4103      BLOCK_SUBBLOCKS (top_block) = replace_blk;
4104    }
4105  else
4106    {
4107      /* We are missing a top level BIND_EXPR. We need one to ensure that we
4108	 don't shuffle around the coroutine frame and corrupt it.  */
4109      tree bind_wrap = build3_loc (fn_start, BIND_EXPR, void_type_node,
4110				   NULL, NULL, NULL);
4111      BIND_EXPR_BODY (bind_wrap) = fnbody;
4112      /* Ensure we have a block to connect up the scopes.  */
4113      tree new_blk = make_node (BLOCK);
4114      BIND_EXPR_BLOCK (bind_wrap) = new_blk;
4115      BLOCK_SUBBLOCKS (top_block) = new_blk;
4116      fnbody = bind_wrap;
4117    }
4118
4119  /* Wrap the function body in a try {} catch (...) {} block, if exceptions
4120     are enabled.  */
4121  tree var_list = NULL_TREE;
4122  tree initial_await = build_init_or_final_await (fn_start, false);
4123
4124  /* [stmt.return.coroutine] / 3
4125     If p.return_void() is a valid expression, flowing off the end of a
4126     coroutine is equivalent to a co_return with no operand; otherwise
4127     flowing off the end of a coroutine results in undefined behavior.  */
4128  tree return_void
4129    = get_coroutine_return_void_expr (current_function_decl, fn_start, false);
4130
4131  /* The pointer to the resume function.  */
4132  tree resume_fn_ptr
4133    = coro_build_artificial_var (fn_start, coro_resume_fn_id,
4134				 resume_fn_ptr_type, orig, NULL_TREE);
4135  DECL_CHAIN (resume_fn_ptr) = var_list;
4136  var_list = resume_fn_ptr;
4137  add_decl_expr (resume_fn_ptr);
4138
4139  /* We will need to be able to set the resume function pointer to nullptr
4140     to signal that the coroutine is 'done'.  */
4141  tree zero_resume
4142    = build1 (CONVERT_EXPR, resume_fn_ptr_type, nullptr_node);
4143
4144  /* The pointer to the destroy function.  */
4145  tree var = coro_build_artificial_var (fn_start, coro_destroy_fn_id,
4146					resume_fn_ptr_type, orig, NULL_TREE);
4147  DECL_CHAIN (var) = var_list;
4148  var_list = var;
4149  add_decl_expr (var);
4150
4151  /* The promise was created on demand when parsing we now link it into
4152      our scope.  */
4153  tree promise = get_coroutine_promise_proxy (orig);
4154  DECL_CONTEXT (promise) = orig;
4155  DECL_SOURCE_LOCATION (promise) = fn_start;
4156  DECL_CHAIN (promise) = var_list;
4157  var_list = promise;
4158  add_decl_expr (promise);
4159
4160  /* We need a handle to this coroutine, which is passed to every
4161     await_suspend().  This was created on demand when parsing we now link it
4162     into our scope.  */
4163  var = get_coroutine_self_handle_proxy (orig);
4164  DECL_CONTEXT (var) = orig;
4165  DECL_SOURCE_LOCATION (var) = fn_start;
4166  DECL_CHAIN (var) = var_list;
4167  var_list = var;
4168  add_decl_expr (var);
4169
4170  /* If we have function parms, then these will be copied to the coroutine
4171     frame.  Create a local (proxy) variable for each parm, since the original
4172     parms will be out of scope once the ramp has finished. The proxy vars will
4173     get DECL_VALUE_EXPRs pointing to the frame copies, so that we can interact
4174     with them in the debugger.  */
4175  if (param_uses)
4176    {
4177      gcc_checking_assert (DECL_ARGUMENTS (orig));
4178      /* Add a local var for each parm.  */
4179      for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
4180	   arg = DECL_CHAIN (arg))
4181	{
4182	  param_info *parm_i = param_uses->get (arg);
4183	  gcc_checking_assert (parm_i);
4184	  parm_i->copy_var
4185	    = build_lang_decl (VAR_DECL, parm_i->field_id, TREE_TYPE (arg));
4186	  DECL_SOURCE_LOCATION (parm_i->copy_var) = DECL_SOURCE_LOCATION (arg);
4187	  DECL_CONTEXT (parm_i->copy_var) = orig;
4188	  DECL_ARTIFICIAL (parm_i->copy_var) = true;
4189	  DECL_CHAIN (parm_i->copy_var) = var_list;
4190	  var_list = parm_i->copy_var;
4191	  add_decl_expr (parm_i->copy_var);
4192      	}
4193
4194      /* Now replace all uses of the parms in the function body with the proxy
4195	 vars.  We want to this to apply to every instance of param's use, so
4196	 don't include a 'visited' hash_set on the tree walk, however we will
4197	 arrange to visit each containing expression only once.  */
4198      hash_set<tree *> visited;
4199      param_frame_data param_data = {NULL, param_uses,
4200				     &visited, fn_start, false};
4201      cp_walk_tree (&fnbody, rewrite_param_uses, &param_data, NULL);
4202    }
4203
4204  /* We create a resume index, this is initialized in the ramp.  */
4205  resume_idx_var
4206    = coro_build_artificial_var (fn_start, coro_resume_index_id,
4207				 short_unsigned_type_node, orig, NULL_TREE);
4208  DECL_CHAIN (resume_idx_var) = var_list;
4209  var_list = resume_idx_var;
4210  add_decl_expr (resume_idx_var);
4211
4212  /* If the coroutine has a frame that needs to be freed, this will be set by
4213     the ramp.  */
4214  var = coro_build_artificial_var (fn_start, coro_frame_needs_free_id,
4215				   boolean_type_node, orig, NULL_TREE);
4216  DECL_CHAIN (var) = var_list;
4217  var_list = var;
4218  add_decl_expr (var);
4219
4220  if (flag_exceptions)
4221    {
4222      /* Build promise.unhandled_exception();  */
4223      tree ueh
4224	= coro_build_promise_expression (current_function_decl, promise,
4225					 coro_unhandled_exception_identifier,
4226					 fn_start, NULL, /*musthave=*/true);
4227      /* Create and initialize the initial-await-resume-called variable per
4228	 [dcl.fct.def.coroutine] / 5.3.  */
4229      tree i_a_r_c
4230	= coro_build_artificial_var (fn_start, coro_frame_i_a_r_c_id,
4231				     boolean_type_node, orig,
4232				     boolean_false_node);
4233      DECL_CHAIN (i_a_r_c) = var_list;
4234      var_list = i_a_r_c;
4235      add_decl_expr (i_a_r_c);
4236      /* Start the try-catch.  */
4237      tree tcb = build_stmt (fn_start, TRY_BLOCK, NULL_TREE, NULL_TREE);
4238      add_stmt (tcb);
4239      TRY_STMTS (tcb) = push_stmt_list ();
4240      if (initial_await != error_mark_node)
4241	{
4242	  /* Build a compound expression that sets the
4243	     initial-await-resume-called variable true and then calls the
4244	     initial suspend expression await resume.
4245	     In the case that the user decides to make the initial await
4246	     await_resume() return a value, we need to discard it and, it is
4247	     a reference type, look past the indirection.  */
4248	  if (INDIRECT_REF_P (initial_await))
4249	    initial_await = TREE_OPERAND (initial_await, 0);
4250	  tree vec = TREE_OPERAND (initial_await, 3);
4251	  tree aw_r = TREE_VEC_ELT (vec, 2);
4252	  aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error);
4253	  tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c,
4254				boolean_true_node);
4255	  aw_r = cp_build_compound_expr (update, aw_r, tf_warning_or_error);
4256	  TREE_VEC_ELT (vec, 2) = aw_r;
4257	}
4258      /* Add the initial await to the start of the user-authored function.  */
4259      finish_expr_stmt (initial_await);
4260      /* Append the original function body.  */
4261      add_stmt (fnbody);
4262      if (return_void)
4263	add_stmt (return_void);
4264      TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb));
4265      TRY_HANDLERS (tcb) = push_stmt_list ();
4266      /* Mimic what the parser does for the catch.  */
4267      tree handler = begin_handler ();
4268      finish_handler_parms (NULL_TREE, handler); /* catch (...) */
4269
4270      /* Get the initial await resume called value.  */
4271      tree not_iarc_if = begin_if_stmt ();
4272      tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR,
4273				  boolean_type_node, i_a_r_c);
4274      finish_if_stmt_cond (not_iarc, not_iarc_if);
4275      /* If the initial await resume called value is false, rethrow...  */
4276      tree rethrow = build_throw (fn_start, NULL_TREE);
4277      suppress_warning (rethrow);
4278      finish_expr_stmt (rethrow);
4279      finish_then_clause (not_iarc_if);
4280      tree iarc_scope = IF_SCOPE (not_iarc_if);
4281      IF_SCOPE (not_iarc_if) = NULL;
4282      not_iarc_if = do_poplevel (iarc_scope);
4283      add_stmt (not_iarc_if);
4284      /* ... else call the promise unhandled exception method
4285	 but first we set done = true and the resume index to 0.
4286	 If the unhandled exception method returns, then we continue
4287	 to the final await expression (which duplicates the clearing of
4288	 the field). */
4289      tree r = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr,
4290		       zero_resume);
4291      finish_expr_stmt (r);
4292      tree short_zero = build_int_cst (short_unsigned_type_node, 0);
4293      r = build2 (MODIFY_EXPR, short_unsigned_type_node, resume_idx_var,
4294		  short_zero);
4295      finish_expr_stmt (r);
4296      finish_expr_stmt (ueh);
4297      finish_handler (handler);
4298      TRY_HANDLERS (tcb) = pop_stmt_list (TRY_HANDLERS (tcb));
4299    }
4300  else
4301    {
4302      if (pedantic)
4303	{
4304	  /* We still try to look for the promise method and warn if it's not
4305	     present.  */
4306	  tree ueh_meth
4307	    = lookup_promise_method (orig, coro_unhandled_exception_identifier,
4308				     fn_start, /*musthave=*/false);
4309	  if (!ueh_meth || ueh_meth == error_mark_node)
4310	    warning_at (fn_start, 0, "no member named %qE in %qT",
4311			coro_unhandled_exception_identifier,
4312			get_coroutine_promise_type (orig));
4313	}
4314      /* Else we don't check and don't care if the method is missing..
4315	 just add the initial suspend, function and return.  */
4316      finish_expr_stmt (initial_await);
4317      /* Append the original function body.  */
4318      add_stmt (fnbody);
4319      if (return_void)
4320	add_stmt (return_void);
4321    }
4322
4323  /* co_return branches to the final_suspend label, so declare that now.  */
4324  fs_label
4325    = create_named_label_with_ctx (fn_start, "final.suspend", NULL_TREE);
4326  add_stmt (build_stmt (fn_start, LABEL_EXPR, fs_label));
4327
4328  /* Before entering the final suspend point, we signal that this point has
4329     been reached by setting the resume function pointer to zero (this is
4330     what the 'done()' builtin tests) as per the current ABI.  */
4331  zero_resume = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr,
4332			zero_resume);
4333  finish_expr_stmt (zero_resume);
4334  finish_expr_stmt (build_init_or_final_await (fn_start, true));
4335  BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body));
4336  BIND_EXPR_VARS (update_body) = nreverse (var_list);
4337  BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body);
4338
4339  return update_body;
4340}
4341
4342/* Here we:
4343   a) Check that the function and promise type are valid for a
4344      coroutine.
4345   b) Carry out the initial morph to create the skeleton of the
4346      coroutine ramp function and the rewritten body.
4347
4348  Assumptions.
4349
4350  1. We only hit this code once all dependencies are resolved.
4351  2. The function body will be either a bind expr or a statement list
4352  3. That cfun and current_function_decl are valid for the case we're
4353     expanding.
4354  4. 'input_location' will be of the final brace for the function.
4355
4356 We do something like this:
4357 declare a dummy coro frame.
4358 struct _R_frame {
4359  using handle_type = coro::coroutine_handle<coro1::promise_type>;
4360  void (*_Coro_resume_fn)(_R_frame *);
4361  void (*_Coro_destroy_fn)(_R_frame *);
4362  coro1::promise_type _Coro_promise;
4363  bool _Coro_frame_needs_free; free the coro frame mem if set.
4364  bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3
4365  short _Coro_resume_index;
4366  handle_type _Coro_self_handle;
4367  parameter copies (were required).
4368  local variables saved (including awaitables)
4369  (maybe) trailing space.
4370 };  */
4371
4372bool
4373morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
4374{
4375  gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL);
4376
4377  *resumer = error_mark_node;
4378  *destroyer = error_mark_node;
4379  if (!coro_function_valid_p (orig))
4380    {
4381      /* For early errors, we do not want a diagnostic about the missing
4382	 ramp return value, since the user cannot fix this - a 'return' is
4383	 not allowed in a coroutine.  */
4384      suppress_warning (orig, OPT_Wreturn_type);
4385      /* Discard the body, we can't process it further.  */
4386      pop_stmt_list (DECL_SAVED_TREE (orig));
4387      DECL_SAVED_TREE (orig) = push_stmt_list ();
4388      return false;
4389    }
4390
4391  /* We can't validly get here with an empty statement list, since there's no
4392     way for the FE to decide it's a coroutine in the absence of any code.  */
4393  tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
4394  gcc_checking_assert (fnbody != NULL_TREE);
4395
4396  /* We don't have the locus of the opening brace - it's filled in later (and
4397     there doesn't really seem to be any easy way to get at it).
4398     The closing brace is assumed to be input_location.  */
4399  location_t fn_start = DECL_SOURCE_LOCATION (orig);
4400  gcc_rich_location fn_start_loc (fn_start);
4401
4402  /* Initial processing of the function-body.
4403     If we have no expressions or just an error then punt.  */
4404  tree body_start = expr_first (fnbody);
4405  if (body_start == NULL_TREE || body_start == error_mark_node)
4406    {
4407      DECL_SAVED_TREE (orig) = push_stmt_list ();
4408      append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig));
4409      /* Suppress warnings about the missing return value.  */
4410      suppress_warning (orig, OPT_Wreturn_type);
4411      return false;
4412    }
4413
4414  /* So, we've tied off the original user-authored body in fn_body.
4415
4416     Start the replacement synthesized ramp body as newbody.
4417     If we encounter a fatal error we might return a now-empty body.
4418
4419     Note, the returned ramp body is not 'popped', to be compatible with
4420     the way that decl.cc handles regular functions, the scope pop is done
4421     in the caller.  */
4422
4423  tree newbody = push_stmt_list ();
4424  DECL_SAVED_TREE (orig) = newbody;
4425
4426  /* If our original body is noexcept, then that's what we apply to our
4427     generated ramp, transfer any MUST_NOT_THOW_EXPR to that.  */
4428  bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
4429  if (is_noexcept)
4430    {
4431      /* The function body we will continue with is the single operand to
4432	 the must-not-throw.  */
4433      fnbody = TREE_OPERAND (body_start, 0);
4434      /* Transfer the must-not-throw to the ramp body.  */
4435      add_stmt (body_start);
4436      /* Re-start the ramp as must-not-throw.  */
4437      TREE_OPERAND (body_start, 0) = push_stmt_list ();
4438    }
4439
4440  /* If the original function has a return value with a non-trivial DTOR
4441     and the body contains a var with a DTOR that might throw, the decl is
4442     marked "throwing_cleanup".
4443     We do not [in the ramp, which is synthesised here], use any body var
4444     types with DTORs that might throw.
4445     The original body is transformed into the actor function which only
4446     contains void returns, and is also wrapped in a try-catch block.
4447     So (a) the 'throwing_cleanup' is not correct for the ramp and (b) we do
4448     not need to transfer it to the actor which only contains void returns.  */
4449  cp_function_chain->throwing_cleanup = false;
4450
4451  /* Create the coro frame type, as far as it can be known at this stage.
4452     1. Types we already know.  */
4453
4454  tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
4455  tree handle_type = get_coroutine_handle_type (orig);
4456  tree promise_type = get_coroutine_promise_type (orig);
4457
4458  /* 2. Types we need to define or look up.  */
4459
4460  tree fr_name = get_fn_local_identifier (orig, "Frame");
4461  tree coro_frame_type = xref_tag (record_type, fr_name);
4462  DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope ();
4463  tree coro_frame_ptr = build_pointer_type (coro_frame_type);
4464  tree act_des_fn_type
4465    = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
4466  tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
4467
4468  /* Declare the actor and destroyer function.  */
4469  tree actor = coro_build_actor_or_destroy_function (orig, act_des_fn_type,
4470						     coro_frame_ptr, true);
4471  tree destroy = coro_build_actor_or_destroy_function (orig, act_des_fn_type,
4472						       coro_frame_ptr, false);
4473
4474  /* Construct the wrapped function body; we will analyze this to determine
4475     the requirements for the coroutine frame.  */
4476
4477  tree resume_idx_var = NULL_TREE;
4478  tree fs_label = NULL_TREE;
4479  hash_map<tree, param_info> *param_uses = analyze_fn_parms (orig);
4480
4481  fnbody = coro_rewrite_function_body (fn_start, fnbody, orig, param_uses,
4482				       act_des_fn_ptr,
4483				       resume_idx_var, fs_label);
4484  /* Build our dummy coro frame layout.  */
4485  coro_frame_type = begin_class_definition (coro_frame_type);
4486
4487  /* The fields for the coro frame.  */
4488  tree field_list = NULL_TREE;
4489
4490  /* We need to know, and inspect, each suspend point in the function
4491     in several places.  It's convenient to place this map out of line
4492     since it's used from tree walk callbacks.  */
4493  suspend_points = new hash_map<tree, suspend_point_info>;
4494
4495  /* Now insert the data for any body await points, at this time we also need
4496     to promote any temporaries that are captured by reference (to regular
4497     vars) they will get added to the coro frame along with other locals.  */
4498  susp_frame_data body_aw_points
4499    = {&field_list, handle_type, fs_label, NULL, NULL, 0, 0,
4500       hash_set<tree> (), NULL, NULL, 0, false, false, false};
4501  body_aw_points.block_stack = make_tree_vector ();
4502  body_aw_points.bind_stack = make_tree_vector ();
4503  body_aw_points.to_replace = make_tree_vector ();
4504  cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);
4505
4506  /* 4. Now make space for local vars, this is conservative again, and we
4507     would expect to delete unused entries later.  */
4508  hash_map<tree, local_var_info> local_var_uses;
4509  local_vars_frame_data local_vars_data
4510    = {&field_list, &local_var_uses, 0, 0, fn_start, false, false};
4511  cp_walk_tree (&fnbody, register_local_var_uses, &local_vars_data, NULL);
4512
4513  /* Tie off the struct for now, so that we can build offsets to the
4514     known entries.  */
4515  TYPE_FIELDS (coro_frame_type) = field_list;
4516  TYPE_BINFO (coro_frame_type) = make_tree_binfo (0);
4517  BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node;
4518  BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type;
4519
4520  coro_frame_type = finish_struct (coro_frame_type, NULL_TREE);
4521
4522  /* Ramp: */
4523  /* Now build the ramp function pieces.  */
4524  tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4525  add_stmt (ramp_bind);
4526  tree ramp_body = push_stmt_list ();
4527
4528  tree zeroinit = build1_loc (fn_start, CONVERT_EXPR,
4529			      coro_frame_ptr, nullptr_node);
4530  tree coro_fp = coro_build_artificial_var (fn_start, "_Coro_frameptr",
4531					    coro_frame_ptr, orig, zeroinit);
4532  tree varlist = coro_fp;
4533
4534  /* To signal that we need to cleanup copied function args.  */
4535  if (flag_exceptions && DECL_ARGUMENTS (orig))
4536    for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
4537	arg = DECL_CHAIN (arg))
4538      {
4539	param_info *parm_i = param_uses->get (arg);
4540	gcc_checking_assert (parm_i);
4541	if (parm_i->trivial_dtor)
4542	  continue;
4543	DECL_CHAIN (parm_i->guard_var) = varlist;
4544	varlist = parm_i->guard_var;
4545      }
4546
4547  /* Signal that we need to clean up the promise object on exception.  */
4548  tree coro_promise_live
4549    = coro_build_artificial_var (fn_start, "_Coro_promise_live",
4550				 boolean_type_node, orig, boolean_false_node);
4551  DECL_CHAIN (coro_promise_live) = varlist;
4552  varlist = coro_promise_live;
4553
4554  /* When the get-return-object is in the RETURN slot, we need to arrange for
4555     cleanup on exception.  */
4556  tree coro_gro_live
4557    = coro_build_artificial_var (fn_start, "_Coro_gro_live",
4558				 boolean_type_node, orig, boolean_false_node);
4559
4560  DECL_CHAIN (coro_gro_live) = varlist;
4561  varlist = coro_gro_live;
4562
4563  /* Collected the scope vars we need ... only one for now. */
4564  BIND_EXPR_VARS (ramp_bind) = nreverse (varlist);
4565
4566  /* We're now going to create a new top level scope block for the ramp
4567     function.  */
4568  tree top_block = make_node (BLOCK);
4569
4570  BIND_EXPR_BLOCK (ramp_bind) = top_block;
4571  BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind);
4572  BLOCK_SUBBLOCKS (top_block) = NULL_TREE;
4573  current_binding_level->blocks = top_block;
4574
4575  /* The decl_expr for the coro frame pointer, initialize to zero so that we
4576     can pass it to the IFN_CO_FRAME (since there's no way to pass a type,
4577     directly apparently).  This avoids a "used uninitialized" warning.  */
4578
4579  add_decl_expr (coro_fp);
4580  if (flag_exceptions && DECL_ARGUMENTS (orig))
4581    for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
4582	arg = DECL_CHAIN (arg))
4583      {
4584	param_info *parm_i = param_uses->get (arg);
4585	if (parm_i->trivial_dtor)
4586	  continue;
4587	add_decl_expr (parm_i->guard_var);;
4588      }
4589  add_decl_expr (coro_promise_live);
4590  add_decl_expr (coro_gro_live);
4591
4592  /* The CO_FRAME internal function is a mechanism to allow the middle end
4593     to adjust the allocation in response to optimizations.  We provide the
4594     current conservative estimate of the frame size (as per the current)
4595     computed layout.  */
4596  tree frame_size = TYPE_SIZE_UNIT (coro_frame_type);
4597  tree resizeable
4598    = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2,
4599				    frame_size, coro_fp);
4600
4601  /* [dcl.fct.def.coroutine] / 10 (part1)
4602    The unqualified-id get_return_object_on_allocation_failure is looked up
4603    in the scope of the promise type by class member access lookup.  */
4604
4605  /* We don't require this, so coro_build_promise_expression can return NULL,
4606     but, if the lookup succeeds, then the function must be usable.  */
4607  tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig));
4608  tree grooaf
4609    = coro_build_promise_expression (orig, dummy_promise,
4610				     coro_gro_on_allocation_fail_identifier,
4611				     fn_start, NULL, /*musthave=*/false);
4612
4613  /* however, should that fail, returning an error, the later stages can't
4614     handle the erroneous expression, so we reset the call as if it was
4615     absent.  */
4616  if (grooaf == error_mark_node)
4617    grooaf = NULL_TREE;
4618
4619  /* Allocate the frame, this has several possibilities:
4620     [dcl.fct.def.coroutine] / 9 (part 1)
4621     The allocation function���s name is looked up in the scope of the promise
4622     type.  It's not a failure for it to be absent see part 4, below.  */
4623
4624  tree nwname = ovl_op_identifier (false, NEW_EXPR);
4625  tree new_fn = NULL_TREE;
4626
4627  if (TYPE_HAS_NEW_OPERATOR (promise_type))
4628    {
4629      tree fns = lookup_promise_method (orig, nwname, fn_start,
4630					/*musthave=*/true);
4631      /* [dcl.fct.def.coroutine] / 9 (part 2)
4632	If the lookup finds an allocation function in the scope of the promise
4633	type, overload resolution is performed on a function call created by
4634	assembling an argument list.  The first argument is the amount of space
4635	requested, and has type std::size_t.  The lvalues p1...pn are the
4636	succeeding arguments..  */
4637      vec<tree, va_gc> *args = make_tree_vector ();
4638      vec_safe_push (args, resizeable); /* Space needed.  */
4639
4640      for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
4641	   arg = DECL_CHAIN (arg))
4642	{
4643	  param_info *parm_i = param_uses->get (arg);
4644	  gcc_checking_assert (parm_i);
4645	  if (parm_i->this_ptr || parm_i->lambda_cobj)
4646	    {
4647	      /* We pass a reference to *this to the allocator lookup.  */
4648	      tree tt = TREE_TYPE (TREE_TYPE (arg));
4649	      tree this_ref = build1 (INDIRECT_REF, tt, arg);
4650	      tt = cp_build_reference_type (tt, false);
4651	      this_ref = convert_to_reference (tt, this_ref, CONV_STATIC,
4652					       LOOKUP_NORMAL , NULL_TREE,
4653					       tf_warning_or_error);
4654	      vec_safe_push (args, convert_from_reference (this_ref));
4655	    }
4656	  else
4657	    vec_safe_push (args, convert_from_reference (arg));
4658	}
4659
4660      /* Note the function selected; we test to see if it's NOTHROW.  */
4661      tree func;
4662      /* Failure is not an error for this attempt.  */
4663      new_fn = build_new_method_call (dummy_promise, fns, &args, NULL,
4664				      LOOKUP_NORMAL, &func, tf_none);
4665      release_tree_vector (args);
4666
4667      if (new_fn == error_mark_node)
4668	{
4669	  /* [dcl.fct.def.coroutine] / 9 (part 3)
4670	    If no viable function is found, overload resolution is performed
4671	    again on a function call created by passing just the amount of
4672	    space required as an argument of type std::size_t.  */
4673	  args = make_tree_vector_single (resizeable); /* Space needed.  */
4674	  new_fn = build_new_method_call (dummy_promise, fns, &args,
4675					  NULL_TREE, LOOKUP_NORMAL, &func,
4676					  tf_none);
4677	  release_tree_vector (args);
4678	}
4679
4680     /* However, if the promise provides an operator new, then one of these
4681	two options must be available.  */
4682    if (new_fn == error_mark_node)
4683      {
4684	error_at (fn_start, "%qE is provided by %qT but is not usable with"
4685		  " the function signature %qD", nwname, promise_type, orig);
4686	new_fn = error_mark_node;
4687      }
4688    else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func)))
4689      error_at (fn_start, "%qE is provided by %qT but %qE is not marked"
4690		" %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname);
4691    else if (!grooaf && TYPE_NOTHROW_P (TREE_TYPE (func)))
4692      warning_at (fn_start, 0, "%qE is marked %<throw()%> or %<noexcept%> but"
4693		  " no usable %<get_return_object_on_allocation_failure%>"
4694		  " is provided by %qT", nwname, promise_type);
4695    }
4696  else /* No operator new in the promise.  */
4697    {
4698      /* [dcl.fct.def.coroutine] / 9 (part 4)
4699	 If this lookup fails, the allocation function���s name is looked up in
4700	 the global scope.  */
4701
4702      vec<tree, va_gc> *args;
4703      /* build_operator_new_call () will insert size needed as element 0 of
4704	 this, and we might need to append the std::nothrow constant.  */
4705      vec_alloc (args, 2);
4706      if (grooaf)
4707	{
4708	  /* [dcl.fct.def.coroutine] / 10 (part 2)
4709	   If any declarations (of the get return on allocation fail) are
4710	   found, then the result of a call to an allocation function used
4711	   to obtain storage for the coroutine state is assumed to return
4712	   nullptr if it fails to obtain storage and, if a global allocation
4713	   function is selected, the ::operator new(size_t, nothrow_t) form
4714	   is used.  The allocation function used in this case shall have a
4715	   non-throwing noexcept-specification.  So we need std::nothrow.  */
4716	  tree std_nt = lookup_qualified_name (std_node,
4717					       get_identifier ("nothrow"),
4718					       LOOK_want::NORMAL,
4719					       /*complain=*/true);
4720	  if (!std_nt || std_nt == error_mark_node)
4721	    error_at (fn_start, "%qE is provided by %qT but %<std::nothrow%> "
4722		      "cannot be found", grooaf, promise_type);
4723	  vec_safe_push (args, std_nt);
4724	}
4725
4726      /* If we get to this point, we must succeed in looking up the global
4727	 operator new for the params provided.  Extract a simplified version
4728	 of the machinery from build_operator_new_call.  This can update the
4729	 frame size.  */
4730      tree cookie = NULL;
4731      new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie,
4732					/*align_arg=*/NULL,
4733					/*size_check=*/NULL, /*fn=*/NULL,
4734					tf_warning_or_error);
4735      resizeable = build_call_expr_internal_loc
4736	(fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp);
4737      /* If the operator call fails for some reason, then don't try to
4738	 amend it.  */
4739      if (new_fn != error_mark_node)
4740	CALL_EXPR_ARG (new_fn, 0) = resizeable;
4741
4742      release_tree_vector (args);
4743    }
4744
4745  tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn);
4746  tree r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, allocated);
4747  r = coro_build_cvt_void_expr_stmt (r, fn_start);
4748  add_stmt (r);
4749
4750  /* If the user provided a method to return an object on alloc fail, then
4751     check the returned pointer and call the func if it's null.
4752     Otherwise, no check, and we fail for noexcept/fno-exceptions cases.  */
4753
4754  if (grooaf)
4755    {
4756      /* [dcl.fct.def.coroutine] / 10 (part 3)
4757	 If the allocation function returns nullptr,the coroutine returns
4758	 control to the caller of the coroutine and the return value is
4759	 obtained by a call to T::get_return_object_on_allocation_failure(),
4760	 where T is the promise type.  */
4761
4762      gcc_checking_assert (same_type_p (fn_return_type, TREE_TYPE (grooaf)));
4763      tree if_stmt = begin_if_stmt ();
4764      tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, nullptr_node);
4765      cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
4766      finish_if_stmt_cond (cond, if_stmt);
4767      if (VOID_TYPE_P (fn_return_type))
4768	{
4769	  /* Execute the get-return-object-on-alloc-fail call...  */
4770	  finish_expr_stmt (grooaf);
4771	  /* ... but discard the result, since we return void.  */
4772	  finish_return_stmt (NULL_TREE);
4773	}
4774      else
4775	{
4776	  /* Get the fallback return object.  */
4777	  r = build_cplus_new (fn_return_type, grooaf, tf_warning_or_error);
4778	  finish_return_stmt (r);
4779	}
4780      finish_then_clause (if_stmt);
4781      finish_if_stmt (if_stmt);
4782    }
4783
4784  /* Up to now any exception thrown will propagate directly to the caller.
4785     This is OK since the only source of such exceptions would be in allocation
4786     of the coroutine frame, and therefore the ramp will not have initialized
4787     any further state.  From here, we will track state that needs explicit
4788     destruction in the case that promise or g.r.o setup fails or an exception
4789     is thrown from the initial suspend expression.  */
4790  tree ramp_cleanup = NULL_TREE;
4791  if (flag_exceptions)
4792    {
4793      ramp_cleanup = build_stmt (fn_start, TRY_BLOCK, NULL, NULL);
4794      add_stmt (ramp_cleanup);
4795      TRY_STMTS (ramp_cleanup) = push_stmt_list ();
4796    }
4797
4798  /* deref the frame pointer, to use in member access code.  */
4799  tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error);
4800
4801  /* For now, once allocation has succeeded we always assume that this needs
4802     destruction, there's no impl. for frame allocation elision.  */
4803  tree fnf_m = lookup_member (coro_frame_type, coro_frame_needs_free_id,
4804			      1, 0,tf_warning_or_error);
4805  tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE,
4806					       false, tf_warning_or_error);
4807  r = build2 (INIT_EXPR, boolean_type_node, fnf_x, boolean_true_node);
4808  r = coro_build_cvt_void_expr_stmt (r, fn_start);
4809  add_stmt (r);
4810
4811  /* Put the resumer and destroyer functions in.  */
4812
4813  tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor);
4814  tree resume_m
4815    = lookup_member (coro_frame_type, coro_resume_fn_id,
4816		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4817  tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE,
4818						  false, tf_warning_or_error);
4819  r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, resume_x, actor_addr);
4820  finish_expr_stmt (r);
4821
4822  tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy);
4823  tree destroy_m
4824    = lookup_member (coro_frame_type, coro_destroy_fn_id,
4825		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4826  tree destroy_x
4827    = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false,
4828				      tf_warning_or_error);
4829  r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, destroy_x, destroy_addr);
4830  finish_expr_stmt (r);
4831
4832  /* [dcl.fct.def.coroutine] /13
4833     When a coroutine is invoked, a copy is created for each coroutine
4834     parameter.  Each such copy is an object with automatic storage duration
4835     that is direct-initialized from an lvalue referring to the corresponding
4836     parameter if the parameter is an lvalue reference, and from an xvalue
4837     referring to it otherwise.  A reference to a parameter in the function-
4838     body of the coroutine and in the call to the coroutine promise
4839     constructor is replaced by a reference to its copy.  */
4840
4841  vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs.  */
4842
4843  /* The initialization and destruction of each parameter copy occurs in the
4844     context of the called coroutine.  Initializations of parameter copies are
4845     sequenced before the call to the coroutine promise constructor and
4846     indeterminately sequenced with respect to each other.  The lifetime of
4847     parameter copies ends immediately after the lifetime of the coroutine
4848     promise object ends.  */
4849
4850  vec<tree, va_gc> *param_dtor_list = NULL;
4851
4852  if (DECL_ARGUMENTS (orig))
4853    {
4854      promise_args = make_tree_vector ();
4855      for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
4856	   arg = DECL_CHAIN (arg))
4857	{
4858	  bool existed;
4859	  param_info &parm = param_uses->get_or_insert (arg, &existed);
4860
4861	  tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
4862					/*protect=*/1, /*want_type=*/0,
4863					tf_warning_or_error);
4864	  tree fld_idx
4865	    = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE,
4866					      false, tf_warning_or_error);
4867
4868	  /* Add this to the promise CTOR arguments list, accounting for
4869	     refs and special handling for method this ptr.  */
4870	  if (parm.this_ptr || parm.lambda_cobj)
4871	    {
4872	      /* We pass a reference to *this to the param preview.  */
4873	      tree tt = TREE_TYPE (arg);
4874	      gcc_checking_assert (POINTER_TYPE_P (tt));
4875	      tree ct = TREE_TYPE (tt);
4876	      tree this_ref = build1 (INDIRECT_REF, ct, arg);
4877	      tree rt = cp_build_reference_type (ct, false);
4878	      this_ref = convert_to_reference (rt, this_ref, CONV_STATIC,
4879					       LOOKUP_NORMAL, NULL_TREE,
4880					       tf_warning_or_error);
4881	      vec_safe_push (promise_args, this_ref);
4882	    }
4883	  else if (parm.rv_ref)
4884	    vec_safe_push (promise_args, move (fld_idx));
4885	  else
4886	    vec_safe_push (promise_args, fld_idx);
4887
4888	  if (parm.rv_ref || parm.pt_ref)
4889	    /* Initialise the frame reference field directly.  */
4890	    r = cp_build_modify_expr (fn_start, TREE_OPERAND (fld_idx, 0),
4891				      INIT_EXPR, arg, tf_warning_or_error);
4892	  else
4893	    {
4894	      r = forward_parm (arg);
4895	      r = cp_build_modify_expr (fn_start, fld_idx, INIT_EXPR, r,
4896					tf_warning_or_error);
4897	    }
4898	  finish_expr_stmt (r);
4899	  if (!parm.trivial_dtor)
4900	    {
4901	      if (param_dtor_list == NULL)
4902		param_dtor_list = make_tree_vector ();
4903	      vec_safe_push (param_dtor_list, parm.field_id);
4904	      /* Cleanup this frame copy on exception.  */
4905	      parm.fr_copy_dtor
4906		= build_special_member_call (fld_idx, complete_dtor_identifier,
4907					     NULL, parm.frame_type,
4908					     LOOKUP_NORMAL,
4909					     tf_warning_or_error);
4910	      if (flag_exceptions)
4911		{
4912		  /* This var is now live.  */
4913		  r = build_modify_expr (fn_start, parm.guard_var,
4914					 boolean_type_node, INIT_EXPR, fn_start,
4915					 boolean_true_node, boolean_type_node);
4916		  finish_expr_stmt (r);
4917		}
4918	    }
4919	}
4920    }
4921
4922  /* Set up the promise.  */
4923  tree promise_m
4924    = lookup_member (coro_frame_type, coro_promise_id,
4925		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4926
4927  tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
4928					   false, tf_warning_or_error);
4929
4930  tree promise_dtor = NULL_TREE;
4931  if (type_build_ctor_call (promise_type))
4932    {
4933      /* Do a placement new constructor for the promise type (we never call
4934	 the new operator, just the constructor on the object in place in the
4935	 frame).
4936
4937	 First try to find a constructor with the same parameter list as the
4938	 original function (if it has params), failing that find a constructor
4939	 with no parameter list.  */
4940
4941      if (DECL_ARGUMENTS (orig))
4942	{
4943	  r = build_special_member_call (p, complete_ctor_identifier,
4944					 &promise_args, promise_type,
4945					 LOOKUP_NORMAL, tf_none);
4946	  release_tree_vector (promise_args);
4947	}
4948      else
4949	r = NULL_TREE;
4950
4951      if (r == NULL_TREE || r == error_mark_node)
4952	r = build_special_member_call (p, complete_ctor_identifier, NULL,
4953				       promise_type, LOOKUP_NORMAL,
4954				       tf_warning_or_error);
4955
4956      r = coro_build_cvt_void_expr_stmt (r, fn_start);
4957      finish_expr_stmt (r);
4958
4959      r = build_modify_expr (fn_start, coro_promise_live, boolean_type_node,
4960			     INIT_EXPR, fn_start, boolean_true_node,
4961			     boolean_type_node);
4962      finish_expr_stmt (r);
4963
4964      promise_dtor
4965	= build_special_member_call (p, complete_dtor_identifier,
4966				     NULL, promise_type, LOOKUP_NORMAL,
4967				     tf_warning_or_error);
4968    }
4969
4970  /* Set up a new bind context for the GRO.  */
4971  tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4972  /* Make and connect the scope blocks.  */
4973  tree gro_block = make_node (BLOCK);
4974  BLOCK_SUPERCONTEXT (gro_block) = top_block;
4975  BLOCK_SUBBLOCKS (top_block) = gro_block;
4976  BIND_EXPR_BLOCK (gro_context_bind) = gro_block;
4977  add_stmt (gro_context_bind);
4978
4979  tree get_ro
4980    = coro_build_promise_expression (orig, p,
4981				     coro_get_return_object_identifier,
4982				     fn_start, NULL, /*musthave=*/true);
4983  /* Without a return object we haven't got much clue what's going on.  */
4984  if (get_ro == error_mark_node)
4985    {
4986      BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
4987      DECL_SAVED_TREE (orig) = newbody;
4988      /* Suppress warnings about the missing return value.  */
4989      suppress_warning (orig, OPT_Wreturn_type);
4990      return false;
4991    }
4992
4993  tree gro_context_body = push_stmt_list ();
4994  tree gro_type = TREE_TYPE (get_ro);
4995  bool gro_is_void_p = VOID_TYPE_P (gro_type);
4996
4997  tree gro = NULL_TREE;
4998  tree gro_bind_vars = NULL_TREE;
4999  /* Used for return objects in the RESULT slot.  */
5000  tree gro_ret_dtor = NULL_TREE;
5001  tree gro_cleanup_stmt = NULL_TREE;
5002  /* We have to sequence the call to get_return_object before initial
5003     suspend.  */
5004  if (gro_is_void_p)
5005    r = get_ro;
5006  else if (same_type_p (gro_type, fn_return_type))
5007    {
5008     /* [dcl.fct.def.coroutine] / 7
5009	The expression promise.get_return_object() is used to initialize the
5010	glvalue result or... (see below)
5011	Construct the return result directly.  */
5012      if (type_build_ctor_call (gro_type))
5013	{
5014	  vec<tree, va_gc> *arg = make_tree_vector_single (get_ro);
5015	  r = build_special_member_call (DECL_RESULT (orig),
5016					 complete_ctor_identifier,
5017					 &arg, gro_type, LOOKUP_NORMAL,
5018					 tf_warning_or_error);
5019	  release_tree_vector (arg);
5020	}
5021      else
5022	r = build2_loc (fn_start, INIT_EXPR, gro_type,
5023			DECL_RESULT (orig), get_ro);
5024
5025      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (gro_type))
5026	/* If some part of the initalization code (prior to the await_resume
5027	     of the initial suspend expression), then we need to clean up the
5028	     return value.  */
5029	gro_ret_dtor
5030	  = build_special_member_call (DECL_RESULT (orig),
5031				       complete_dtor_identifier, NULL,
5032				       gro_type, LOOKUP_NORMAL,
5033				       tf_warning_or_error);
5034    }
5035  else
5036    {
5037      /* ... or ... Construct an object that will be used as the single
5038	param to the CTOR for the return object.  */
5039      gro = coro_build_artificial_var (fn_start, "_Coro_gro", gro_type, orig,
5040				       NULL_TREE);
5041      add_decl_expr (gro);
5042      gro_bind_vars = gro;
5043      r = cp_build_modify_expr (input_location, gro, INIT_EXPR, get_ro,
5044				tf_warning_or_error);
5045      /* The constructed object might require a cleanup.  */
5046      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (gro_type))
5047	{
5048	  gro_cleanup_stmt
5049	    = build_special_member_call (gro, complete_dtor_identifier,
5050					 NULL, gro_type, LOOKUP_NORMAL,
5051					 tf_warning_or_error);
5052	  gro_cleanup_stmt = build_stmt (input_location, CLEANUP_STMT, NULL,
5053					 gro_cleanup_stmt, gro);
5054	}
5055    }
5056  finish_expr_stmt (r);
5057
5058  if (gro_cleanup_stmt && gro_cleanup_stmt != error_mark_node)
5059    CLEANUP_BODY (gro_cleanup_stmt) = push_stmt_list ();
5060
5061  /* If we have a live g.r.o in the return slot, then signal this for exception
5062     cleanup.  */
5063  if (gro_ret_dtor)
5064    {
5065       r = build_modify_expr (fn_start, coro_gro_live, boolean_type_node,
5066			      INIT_EXPR, fn_start, boolean_true_node,
5067			      boolean_type_node);
5068      finish_expr_stmt (r);
5069    }
5070  /* Initialize the resume_idx_var to 0, meaning "not started".  */
5071  tree resume_idx_m
5072    = lookup_member (coro_frame_type, coro_resume_index_id,
5073		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
5074  tree resume_idx
5075    = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false,
5076				      tf_warning_or_error);
5077  r = build_int_cst (short_unsigned_type_node, 0);
5078  r = build2_loc (fn_start, INIT_EXPR, short_unsigned_type_node, resume_idx, r);
5079  r = coro_build_cvt_void_expr_stmt (r, fn_start);
5080  add_stmt (r);
5081
5082  /* So .. call the actor ..  */
5083  r = build_call_expr_loc (fn_start, actor, 1, coro_fp);
5084  r = maybe_cleanup_point_expr_void (r);
5085  add_stmt (r);
5086
5087  /* Switch to using 'input_location' as the loc, since we're now more
5088     logically doing things related to the end of the function.  */
5089
5090  /* The ramp is done, we just need the return value.
5091     [dcl.fct.def.coroutine] / 7
5092     The expression promise.get_return_object() is used to initialize the
5093     glvalue result or prvalue result object of a call to a coroutine.
5094
5095     If the 'get return object' is non-void, then we built it before the
5096     promise was constructed.  We now supply a reference to that var,
5097     either as the return value (if it's the same type) or to the CTOR
5098     for an object of the return type.  */
5099
5100  if (same_type_p (gro_type, fn_return_type))
5101    r = gro_is_void_p ? NULL_TREE : DECL_RESULT (orig);
5102  else if (!gro_is_void_p)
5103    /* check_return_expr will automatically return gro as an rvalue via
5104       treat_lvalue_as_rvalue_p.  */
5105    r = gro;
5106  else if (CLASS_TYPE_P (fn_return_type))
5107    {
5108      /* For class type return objects, we can attempt to construct,
5109	 even if the gro is void. ??? Citation ??? c++/100476  */
5110      r = build_special_member_call (NULL_TREE,
5111				     complete_ctor_identifier, NULL,
5112				     fn_return_type, LOOKUP_NORMAL,
5113				     tf_warning_or_error);
5114      r = build_cplus_new (fn_return_type, r, tf_warning_or_error);
5115    }
5116  else
5117    {
5118      /* We can't initialize a non-class return value from void.  */
5119      error_at (input_location, "cannot initialize a return object of type"
5120		" %qT with an rvalue of type %<void%>", fn_return_type);
5121      r = error_mark_node;
5122    }
5123
5124  finish_return_stmt (r);
5125
5126  if (gro_cleanup_stmt)
5127    {
5128      CLEANUP_BODY (gro_cleanup_stmt)
5129	= pop_stmt_list (CLEANUP_BODY (gro_cleanup_stmt));
5130      add_stmt (gro_cleanup_stmt);
5131    }
5132
5133  /* Finish up the ramp function.  */
5134  BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
5135  BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
5136  TREE_SIDE_EFFECTS (gro_context_bind) = true;
5137
5138  if (flag_exceptions)
5139    {
5140      TRY_HANDLERS (ramp_cleanup) = push_stmt_list ();
5141      tree handler = begin_handler ();
5142      finish_handler_parms (NULL_TREE, handler); /* catch (...) */
5143
5144      /* If we have a live G.R.O in the return slot, then run its DTOR.
5145     When the return object is constructed from a separate g.r.o, this is
5146     already handled by its regular cleanup.  */
5147      if (gro_ret_dtor && gro_ret_dtor != error_mark_node)
5148	{
5149	  tree gro_d_if = begin_if_stmt ();
5150	  finish_if_stmt_cond (coro_gro_live, gro_d_if);
5151	  finish_expr_stmt (gro_ret_dtor);
5152	  finish_then_clause (gro_d_if);
5153	  tree gro_d_if_scope = IF_SCOPE (gro_d_if);
5154	  IF_SCOPE (gro_d_if) = NULL;
5155	  gro_d_if = do_poplevel (gro_d_if_scope);
5156	  add_stmt (gro_d_if);
5157	}
5158
5159      /* If the promise is live, then run its dtor if that's available.  */
5160      if (promise_dtor && promise_dtor != error_mark_node)
5161	{
5162	  tree promise_d_if = begin_if_stmt ();
5163	  finish_if_stmt_cond (coro_promise_live, promise_d_if);
5164	  finish_expr_stmt (promise_dtor);
5165	  finish_then_clause (promise_d_if);
5166	  tree promise_d_if_scope = IF_SCOPE (promise_d_if);
5167	  IF_SCOPE (promise_d_if) = NULL;
5168	  promise_d_if = do_poplevel (promise_d_if_scope);
5169	  add_stmt (promise_d_if);
5170	}
5171
5172      /* Clean up any frame copies of parms with non-trivial dtors.  */
5173      if (DECL_ARGUMENTS (orig))
5174	for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
5175	     arg = DECL_CHAIN (arg))
5176	  {
5177	    param_info *parm_i = param_uses->get (arg);
5178	    if (parm_i->trivial_dtor)
5179	      continue;
5180	    if (parm_i->fr_copy_dtor && parm_i->fr_copy_dtor != error_mark_node)
5181	      {
5182		tree dtor_if = begin_if_stmt ();
5183		finish_if_stmt_cond (parm_i->guard_var, dtor_if);
5184		finish_expr_stmt (parm_i->fr_copy_dtor);
5185		finish_then_clause (dtor_if);
5186		tree parm_d_if_scope = IF_SCOPE (dtor_if);
5187		IF_SCOPE (dtor_if) = NULL;
5188		dtor_if = do_poplevel (parm_d_if_scope);
5189		add_stmt (dtor_if);
5190	      }
5191	  }
5192
5193      /* We always expect to delete the frame.  */
5194      tree del_coro_fr = coro_get_frame_dtor (coro_fp, orig, frame_size,
5195					      promise_type, fn_start);
5196      finish_expr_stmt (del_coro_fr);
5197      tree rethrow = build_throw (fn_start, NULL_TREE);
5198      suppress_warning (rethrow);
5199      finish_expr_stmt (rethrow);
5200      finish_handler (handler);
5201      TRY_HANDLERS (ramp_cleanup) = pop_stmt_list (TRY_HANDLERS (ramp_cleanup));
5202    }
5203
5204  BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
5205  TREE_SIDE_EFFECTS (ramp_bind) = true;
5206
5207  /* Start to build the final functions.
5208
5209     We push_deferring_access_checks to avoid these routines being seen as
5210     nested by the middle end; we are doing the outlining here.  */
5211
5212  push_deferring_access_checks (dk_no_check);
5213
5214  /* Build the actor...  */
5215  build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig,
5216		  &local_var_uses, param_dtor_list,
5217		  resume_idx_var, body_aw_points.await_number, frame_size);
5218
5219  /* Destroyer ... */
5220  build_destroy_fn (fn_start, coro_frame_type, destroy, actor);
5221
5222  pop_deferring_access_checks ();
5223
5224  DECL_SAVED_TREE (orig) = newbody;
5225  /* Link our new functions into the list.  */
5226  TREE_CHAIN (destroy) = TREE_CHAIN (orig);
5227  TREE_CHAIN (actor) = destroy;
5228  TREE_CHAIN (orig) = actor;
5229
5230  *resumer = actor;
5231  *destroyer = destroy;
5232
5233  delete suspend_points;
5234  suspend_points = NULL;
5235  return true;
5236}
5237
5238#include "gt-cp-coroutines.h"
5239
5240