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