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