coroutines: Revise await expansions [PR94528]
[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_node = TYPE_ARG_TYPES (functyp);
300 tree argtypes = make_tree_vec (list_length (arg_node)-1);
301 unsigned p = 0;
302
303 while (arg_node != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (arg_node)))
304 {
305 TREE_VEC_ELT (argtypes, p++) = TREE_VALUE (arg_node);
306 arg_node = TREE_CHAIN (arg_node);
307 }
308
309 tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
310 SET_ARGUMENT_PACK_ARGS (argtypepack, argtypes);
311
312 tree targ = make_tree_vec (2);
313 TREE_VEC_ELT (targ, 0) = TREE_TYPE (functyp);
314 TREE_VEC_ELT (targ, 1) = argtypepack;
315
316 tree traits_class
317 = lookup_template_class (coro_traits_templ, targ,
318 /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE,
319 /*entering scope=*/false, tf_warning_or_error);
320
321 if (traits_class == error_mark_node)
322 {
323 error_at (kw, "cannot instantiate %<coroutine traits%>");
324 return NULL_TREE;
325 }
326
327 return traits_class;
328 }
329
330 /* [coroutine.handle] */
331
332 static tree
333 find_coro_handle_template_decl (location_t kw)
334 {
335 /* As for the coroutine traits, this error is per TU, so only emit
336 it once. */
337 static bool coro_handle_error_emitted = false;
338 tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier,
339 0, !coro_handle_error_emitted);
340 if (handle_decl == error_mark_node
341 || !DECL_CLASS_TEMPLATE_P (handle_decl))
342 {
343 if (!coro_handle_error_emitted)
344 error_at (kw, "coroutines require a handle class template;"
345 " cannot find %<%E::%E%>", std_node, coro_handle_identifier);
346 coro_handle_error_emitted = true;
347 return NULL_TREE;
348 }
349 else
350 return handle_decl;
351 }
352
353 /* Instantiate the handle template for a given promise type. */
354
355 static tree
356 instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type)
357 {
358 /* So now build up a type list for the template, one entry, the promise. */
359 tree targ = make_tree_vec (1);
360 TREE_VEC_ELT (targ, 0) = promise_type;
361 tree handle_type
362 = lookup_template_class (coro_handle_identifier, targ,
363 /* in_decl=*/NULL_TREE,
364 /* context=*/std_node,
365 /* entering scope=*/false, tf_warning_or_error);
366
367 if (handle_type == error_mark_node)
368 {
369 error_at (kw, "cannot instantiate a %<coroutine handle%> for"
370 " promise type %qT", promise_type);
371 return NULL_TREE;
372 }
373
374 return handle_type;
375 }
376
377 /* Look for the promise_type in the instantiated traits. */
378
379 static tree
380 find_promise_type (tree traits_class)
381 {
382 tree promise_type
383 = lookup_member (traits_class, coro_promise_type_identifier,
384 /* protect=*/1, /*want_type=*/true, tf_warning_or_error);
385
386 if (promise_type)
387 promise_type
388 = complete_type_or_else (TREE_TYPE (promise_type), promise_type);
389
390 /* NULL_TREE on fail. */
391 return promise_type;
392 }
393
394 static bool
395 coro_promise_type_found_p (tree fndecl, location_t loc)
396 {
397 gcc_assert (fndecl != NULL_TREE);
398
399 if (!coro_initialized)
400 {
401 /* Trees we only need to create once.
402 Set up the identifiers we will use. */
403 coro_init_identifiers ();
404
405 /* Coroutine traits template. */
406 coro_traits_templ = find_coro_traits_template_decl (loc);
407 if (coro_traits_templ == NULL_TREE)
408 return false;
409
410 /* coroutine_handle<> template. */
411 coro_handle_templ = find_coro_handle_template_decl (loc);
412 if (coro_handle_templ == NULL_TREE)
413 return false;
414
415 /* We can also instantiate the void coroutine_handle<> */
416 void_coro_handle_type =
417 instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
418 if (void_coro_handle_type == NULL_TREE)
419 return false;
420
421 /* A table to hold the state, per coroutine decl. */
422 gcc_checking_assert (coroutine_info_table == NULL);
423 coroutine_info_table =
424 hash_table<coroutine_info_hasher>::create_ggc (11);
425
426 if (coroutine_info_table == NULL)
427 return false;
428
429 coro_initialized = true;
430 }
431
432 /* Save the coroutine data on the side to avoid the overhead on every
433 function decl tree. */
434
435 coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
436 /* Without this, we cannot really proceed. */
437 gcc_checking_assert (coro_info);
438
439 /* If we don't already have a current promise type, try to look it up. */
440 if (coro_info->promise_type == NULL_TREE)
441 {
442 /* Get the coroutine traits template class instance for the function
443 signature we have - coroutine_traits <R, ...> */
444 tree return_type = TREE_TYPE (TREE_TYPE (fndecl));
445 if (!CLASS_TYPE_P (return_type))
446 {
447 /* It makes more sense to show the function header for this, even
448 though we will have encountered it when processing a keyword.
449 Only emit the error once, not for every keyword we encounter. */
450 if (!coro_info->coro_ret_type_error_emitted)
451 error_at (DECL_SOURCE_LOCATION (fndecl), "coroutine return type"
452 " %qT is not a class", return_type);
453 coro_info->coro_ret_type_error_emitted = true;
454 return false;
455 }
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 (TREE_CODE (*stmt) == BIND_EXPR)
1631 res = cp_walk_tree (&BIND_EXPR_BODY (*stmt), await_statement_expander,
1632 d, NULL);
1633 else if (TREE_CODE (*stmt) == STATEMENT_LIST)
1634 {
1635 tree_stmt_iterator i;
1636 for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i))
1637 {
1638 res = cp_walk_tree (tsi_stmt_ptr (i), await_statement_expander,
1639 d, NULL);
1640 if (res)
1641 return res;
1642 }
1643 *do_subtree = 0; /* Done subtrees. */
1644 }
1645 else if (STATEMENT_CLASS_P (*stmt))
1646 return NULL_TREE; /* Process the sub-trees. */
1647 else if (EXPR_P (*stmt))
1648 {
1649 process_one_statement (stmt, d);
1650 *do_subtree = 0; /* Done subtrees. */
1651 }
1652
1653 /* Continue statement walk, where required. */
1654 return res;
1655 }
1656
1657 /* Suspend point hash_map. */
1658
1659 struct suspend_point_info
1660 {
1661 /* coro frame field type. */
1662 tree awaitable_type;
1663 /* coro frame field name. */
1664 tree await_field_id;
1665 };
1666
1667 static hash_map<tree, suspend_point_info> *suspend_points;
1668
1669 struct await_xform_data
1670 {
1671 tree actor_fn; /* Decl for context. */
1672 tree actor_frame;
1673 tree promise_proxy;
1674 tree real_promise;
1675 tree self_h_proxy;
1676 tree real_self_h;
1677 };
1678
1679 /* When we built the await expressions, we didn't know the coro frame
1680 layout, therefore no idea where to find the promise or where to put
1681 the awaitables. Now we know these things, fill them in. */
1682
1683 static tree
1684 transform_await_expr (tree await_expr, await_xform_data *xform)
1685 {
1686 suspend_point_info *si = suspend_points->get (await_expr);
1687 location_t loc = EXPR_LOCATION (await_expr);
1688 if (!si)
1689 {
1690 error_at (loc, "no suspend point info for %qD", await_expr);
1691 return error_mark_node;
1692 }
1693
1694 /* So, on entry, we have:
1695 in : CO_AWAIT_EXPR (a, e_proxy, o, awr_call_vector, mode)
1696 We no longer need a [it had diagnostic value, maybe?]
1697 We need to replace the promise proxy in all elements
1698 We need to replace the e_proxy in the awr_call. */
1699
1700 tree coro_frame_type = TREE_TYPE (xform->actor_frame);
1701
1702 /* If we have a frame var for the awaitable, get a reference to it. */
1703 proxy_replace data;
1704 if (si->await_field_id)
1705 {
1706 tree as_m
1707 = lookup_member (coro_frame_type, si->await_field_id,
1708 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
1709 tree as = build_class_member_access_expr (xform->actor_frame, as_m,
1710 NULL_TREE, true,
1711 tf_warning_or_error);
1712
1713 /* Replace references to the instance proxy with the frame entry now
1714 computed. */
1715 data.from = TREE_OPERAND (await_expr, 1);
1716 data.to = as;
1717 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1718
1719 /* .. and replace. */
1720 TREE_OPERAND (await_expr, 1) = as;
1721 }
1722
1723 /* Now do the self_handle. */
1724 data.from = xform->self_h_proxy;
1725 data.to = xform->real_self_h;
1726 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1727
1728 /* Now do the promise. */
1729 data.from = xform->promise_proxy;
1730 data.to = xform->real_promise;
1731 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1732
1733 return await_expr;
1734 }
1735
1736 /* A wrapper for the transform_await_expr function so that it can be a
1737 callback from cp_walk_tree. */
1738
1739 static tree
1740 transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
1741 {
1742 /* Set actor function as new DECL_CONTEXT of label_decl. */
1743 struct await_xform_data *xform = (struct await_xform_data *) d;
1744 if (TREE_CODE (*stmt) == LABEL_DECL
1745 && DECL_CONTEXT (*stmt) != xform->actor_fn)
1746 DECL_CONTEXT (*stmt) = xform->actor_fn;
1747
1748 if (TREE_CODE (*stmt) != CO_AWAIT_EXPR && TREE_CODE (*stmt) != CO_YIELD_EXPR)
1749 return NULL_TREE;
1750
1751 tree await_expr = *stmt;
1752 *stmt = transform_await_expr (await_expr, xform);
1753 if (*stmt == error_mark_node)
1754 *do_subtree = 0;
1755 return NULL_TREE;
1756 }
1757
1758 /* This caches information that we determine about function params,
1759 their uses and copies in the coroutine frame. */
1760
1761 struct param_info
1762 {
1763 tree field_id; /* The name of the copy in the coroutine frame. */
1764 vec<tree *> *body_uses; /* Worklist of uses, void if there are none. */
1765 tree frame_type; /* The type used to represent this parm in the frame. */
1766 tree orig_type; /* The original type of the parm (not as passed). */
1767 bool by_ref; /* Was passed by reference. */
1768 bool rv_ref; /* Was an rvalue reference. */
1769 bool pt_ref; /* Was a pointer to object. */
1770 bool trivial_dtor; /* The frame type has a trivial DTOR. */
1771 };
1772
1773 struct local_var_info
1774 {
1775 tree field_id;
1776 tree field_idx;
1777 tree frame_type;
1778 bool is_lambda_capture;
1779 location_t def_loc;
1780 };
1781
1782 /* For figuring out what local variable usage we have. */
1783 struct local_vars_transform
1784 {
1785 tree context;
1786 tree actor_frame;
1787 tree coro_frame_type;
1788 location_t loc;
1789 hash_map<tree, local_var_info> *local_var_uses;
1790 };
1791
1792 static tree
1793 transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
1794 {
1795 local_vars_transform *lvd = (local_vars_transform *) d;
1796
1797 /* For each var in this bind expr (that has a frame id, which means it was
1798 accessed), build a frame reference for each and then walk the bind expr
1799 statements, substituting the frame ref for the original var. */
1800
1801 if (TREE_CODE (*stmt) == BIND_EXPR)
1802 {
1803 tree lvar;
1804 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
1805 lvar = DECL_CHAIN (lvar))
1806 {
1807 bool existed;
1808 local_var_info &local_var
1809 = lvd->local_var_uses->get_or_insert (lvar, &existed);
1810 gcc_checking_assert (existed);
1811
1812 /* Re-write the variable's context to be in the actor func. */
1813 DECL_CONTEXT (lvar) = lvd->context;
1814
1815 /* we need to walk some of the decl trees, which might contain
1816 references to vars replaced at a higher level. */
1817 cp_walk_tree (&DECL_INITIAL (lvar), transform_local_var_uses, d,
1818 NULL);
1819 cp_walk_tree (&DECL_SIZE (lvar), transform_local_var_uses, d, NULL);
1820 cp_walk_tree (&DECL_SIZE_UNIT (lvar), transform_local_var_uses, d,
1821 NULL);
1822
1823 /* For capture proxies, this could include the decl value expr. */
1824 if (local_var.is_lambda_capture)
1825 {
1826 tree ve = DECL_VALUE_EXPR (lvar);
1827 cp_walk_tree (&ve, transform_local_var_uses, d, NULL);
1828 continue; /* No frame entry for this. */
1829 }
1830
1831 /* TODO: implement selective generation of fields when vars are
1832 known not-used. */
1833 if (local_var.field_id == NULL_TREE)
1834 continue; /* Wasn't used. */
1835
1836 tree fld_ref
1837 = lookup_member (lvd->coro_frame_type, local_var.field_id,
1838 /*protect=*/1, /*want_type=*/0,
1839 tf_warning_or_error);
1840 tree fld_idx = build3_loc (lvd->loc, COMPONENT_REF, TREE_TYPE (lvar),
1841 lvd->actor_frame, fld_ref, NULL_TREE);
1842 local_var.field_idx = fld_idx;
1843 }
1844 cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
1845
1846 /* Now we have processed and removed references to the original vars,
1847 we can drop those from the bind - leaving capture proxies alone. */
1848 for (tree *pvar = &BIND_EXPR_VARS (*stmt); *pvar != NULL;)
1849 {
1850 bool existed;
1851 local_var_info &local_var
1852 = lvd->local_var_uses->get_or_insert (*pvar, &existed);
1853 gcc_checking_assert (existed);
1854
1855 /* Leave lambda closure captures alone, we replace the *this
1856 pointer with the frame version and let the normal process
1857 deal with the rest. */
1858 if (local_var.is_lambda_capture)
1859 {
1860 pvar = &DECL_CHAIN (*pvar);
1861 continue;
1862 }
1863
1864 /* It's not used, but we can let the optimizer deal with that. */
1865 if (local_var.field_id == NULL_TREE)
1866 {
1867 pvar = &DECL_CHAIN (*pvar);
1868 continue;
1869 }
1870
1871 /* Discard this one, we replaced it. */
1872 *pvar = DECL_CHAIN (*pvar);
1873 }
1874
1875 *do_subtree = 0; /* We've done the body already. */
1876 return NULL_TREE;
1877 }
1878
1879 tree var_decl = *stmt;
1880 /* Look inside cleanups, we don't want to wrap a statement list in a
1881 cleanup. */
1882 bool needs_cleanup = true;
1883 if (TREE_CODE (var_decl) == CLEANUP_POINT_EXPR)
1884 var_decl = TREE_OPERAND (var_decl, 0);
1885 else
1886 needs_cleanup = false;
1887
1888 /* Look inside the decl_expr for the actual var. */
1889 bool decl_expr_p = TREE_CODE (var_decl) == DECL_EXPR;
1890 if (decl_expr_p && TREE_CODE (DECL_EXPR_DECL (var_decl)) == VAR_DECL)
1891 var_decl = DECL_EXPR_DECL (var_decl);
1892 else if (TREE_CODE (var_decl) != VAR_DECL)
1893 return NULL_TREE;
1894
1895 /* VAR_DECLs that are not recorded can belong to the proxies we've placed
1896 for the promise and coroutine handle(s), to global vars or to compiler
1897 temporaries. Skip past these, we will handle them later. */
1898 local_var_info *local_var_i = lvd->local_var_uses->get (var_decl);
1899 if (local_var_i == NULL)
1900 return NULL_TREE;
1901
1902 if (local_var_i->is_lambda_capture)
1903 return NULL_TREE;
1904
1905 /* This is our revised 'local' i.e. a frame slot. */
1906 tree revised = local_var_i->field_idx;
1907 gcc_checking_assert (DECL_CONTEXT (var_decl) == lvd->context);
1908
1909 if (decl_expr_p && DECL_INITIAL (var_decl))
1910 {
1911 location_t loc = DECL_SOURCE_LOCATION (var_decl);
1912 tree r
1913 = cp_build_modify_expr (loc, revised, INIT_EXPR,
1914 DECL_INITIAL (var_decl), tf_warning_or_error);
1915 if (needs_cleanup)
1916 r = coro_build_cvt_void_expr_stmt (r, EXPR_LOCATION (*stmt));
1917 *stmt = r;
1918 }
1919 else
1920 *stmt = revised;
1921
1922 if (decl_expr_p)
1923 *do_subtree = 0; /* We've accounted for the nested use. */
1924 return NULL_TREE;
1925 }
1926
1927 /* The actor transform. */
1928
1929 static void
1930 build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
1931 tree orig, hash_map<tree, param_info> *param_uses,
1932 hash_map<tree, local_var_info> *local_var_uses,
1933 vec<tree, va_gc> *param_dtor_list, tree initial_await,
1934 tree final_await, unsigned body_count, tree frame_size)
1935 {
1936 verify_stmt_tree (fnbody);
1937 /* Some things we inherit from the original function. */
1938 tree coro_frame_ptr = build_pointer_type (coro_frame_type);
1939 tree handle_type = get_coroutine_handle_type (orig);
1940 tree self_h_proxy = get_coroutine_self_handle_proxy (orig);
1941 tree promise_type = get_coroutine_promise_type (orig);
1942 tree promise_proxy = get_coroutine_promise_proxy (orig);
1943 tree act_des_fn_type
1944 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
1945 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
1946
1947 /* One param, the coro frame pointer. */
1948 tree actor_fp = DECL_ARGUMENTS (actor);
1949
1950 /* A void return. */
1951 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
1952 DECL_ARTIFICIAL (resdecl) = 1;
1953 DECL_IGNORED_P (resdecl) = 1;
1954 DECL_RESULT (actor) = resdecl;
1955 DECL_COROUTINE_P (actor) = 1;
1956
1957 /* We have a definition here. */
1958 TREE_STATIC (actor) = 1;
1959
1960 tree actor_outer = push_stmt_list ();
1961 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
1962 tree stmt = begin_compound_stmt (BCS_FN_BODY);
1963
1964 /* ??? Can we dispense with the enclosing bind if the function body does
1965 not start with a bind_expr? (i.e. there's no contained scopes). */
1966 tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
1967 tree top_block = make_node (BLOCK);
1968 BIND_EXPR_BLOCK (actor_bind) = top_block;
1969
1970 tree continuation = build_lang_decl (VAR_DECL,
1971 get_identifier ("actor.continue"),
1972 void_coro_handle_type);
1973 DECL_ARTIFICIAL (continuation) = 1;
1974 DECL_IGNORED_P (continuation) = 1;
1975 DECL_CONTEXT (continuation) = actor;
1976 BIND_EXPR_VARS (actor_bind) = continuation;
1977
1978 /* Update the block associated with the outer scope of the orig fn. */
1979 tree first = expr_first (fnbody);
1980 if (first && TREE_CODE (first) == BIND_EXPR)
1981 {
1982 /* We will discard this, since it's connected to the original scope
1983 nest. */
1984 tree block = BIND_EXPR_BLOCK (first);
1985 if (block) /* For this to be missing is probably a bug. */
1986 {
1987 gcc_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
1988 gcc_assert (BLOCK_CHAIN (block) == NULL_TREE);
1989 BLOCK_SUPERCONTEXT (block) = top_block;
1990 BLOCK_SUBBLOCKS (top_block) = block;
1991 }
1992 }
1993
1994 add_stmt (actor_bind);
1995 tree actor_body = push_stmt_list ();
1996
1997 /* The entry point for the actor code from the ramp. */
1998 tree actor_begin_label
1999 = create_named_label_with_ctx (loc, "actor.begin", actor);
2000 tree actor_frame = build1_loc (loc, INDIRECT_REF, coro_frame_type, actor_fp);
2001
2002 /* Declare the continuation handle. */
2003 add_decl_expr (continuation);
2004
2005 /* Re-write param references in the body, no code should be generated
2006 here. */
2007 if (DECL_ARGUMENTS (orig))
2008 {
2009 tree arg;
2010 for (arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
2011 {
2012 bool existed;
2013 param_info &parm = param_uses->get_or_insert (arg, &existed);
2014 if (!parm.body_uses)
2015 continue; /* Wasn't used in the orignal function body. */
2016
2017 tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
2018 /*protect=*/1, /*want_type=*/0,
2019 tf_warning_or_error);
2020 tree fld_idx = build3_loc (loc, COMPONENT_REF, parm.frame_type,
2021 actor_frame, fld_ref, NULL_TREE);
2022
2023 /* We keep these in the frame as a regular pointer, so convert that
2024 back to the type expected. */
2025 if (parm.pt_ref)
2026 fld_idx = build1_loc (loc, CONVERT_EXPR, TREE_TYPE (arg), fld_idx);
2027
2028 /* We expect an rvalue ref. here. */
2029 if (parm.rv_ref)
2030 fld_idx = convert_to_reference (DECL_ARG_TYPE (arg), fld_idx,
2031 CONV_STATIC, LOOKUP_NORMAL,
2032 NULL_TREE, tf_warning_or_error);
2033
2034 int i;
2035 tree *puse;
2036 FOR_EACH_VEC_ELT (*parm.body_uses, i, puse)
2037 *puse = fld_idx;
2038 }
2039 }
2040
2041 /* Re-write local vars, similarly. */
2042 local_vars_transform xform_vars_data
2043 = {actor, actor_frame, coro_frame_type, loc, local_var_uses};
2044 cp_walk_tree (&fnbody, transform_local_var_uses, &xform_vars_data, NULL);
2045
2046 tree resume_idx_name = get_identifier ("__resume_at");
2047 tree rat_field = lookup_member (coro_frame_type, resume_idx_name, 1, 0,
2048 tf_warning_or_error);
2049 tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, actor_frame,
2050 rat_field, NULL_TREE);
2051
2052 tree ret_label
2053 = create_named_label_with_ctx (loc, "actor.suspend.ret", actor);
2054
2055 tree continue_label
2056 = create_named_label_with_ctx (loc, "actor.continue.ret", actor);
2057
2058 tree lsb_if = begin_if_stmt ();
2059 tree chkb0 = build2 (BIT_AND_EXPR, short_unsigned_type_node, rat,
2060 build_int_cst (short_unsigned_type_node, 1));
2061 chkb0 = build2 (NE_EXPR, short_unsigned_type_node, chkb0,
2062 build_int_cst (short_unsigned_type_node, 0));
2063 finish_if_stmt_cond (chkb0, lsb_if);
2064
2065 tree destroy_dispatcher = begin_switch_stmt ();
2066 finish_switch_cond (rat, destroy_dispatcher);
2067 tree ddeflab = build_case_label (NULL_TREE, NULL_TREE,
2068 create_anon_label_with_ctx (loc, actor));
2069 add_stmt (ddeflab);
2070 tree b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2071 b = coro_build_cvt_void_expr_stmt (b, loc);
2072 add_stmt (b);
2073
2074 short unsigned lab_num = 3;
2075 for (unsigned destr_pt = 0; destr_pt < body_count + 2; destr_pt++)
2076 {
2077 tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2078 b = build_case_label (l_num, NULL_TREE,
2079 create_anon_label_with_ctx (loc, actor));
2080 add_stmt (b);
2081 b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2082 l_num);
2083 b = coro_build_cvt_void_expr_stmt (b, loc);
2084 add_stmt (b);
2085 b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (ddeflab));
2086 add_stmt (b);
2087 lab_num += 2;
2088 }
2089
2090 /* Insert the prototype dispatcher. */
2091 finish_switch_stmt (destroy_dispatcher);
2092
2093 finish_then_clause (lsb_if);
2094
2095 tree dispatcher = begin_switch_stmt ();
2096 finish_switch_cond (rat, dispatcher);
2097 b = build_case_label (build_int_cst (short_unsigned_type_node, 0), NULL_TREE,
2098 create_anon_label_with_ctx (loc, actor));
2099 add_stmt (b);
2100 b = build1 (GOTO_EXPR, void_type_node, actor_begin_label);
2101 add_stmt (b);
2102
2103 tree rdeflab = build_case_label (NULL_TREE, NULL_TREE,
2104 create_anon_label_with_ctx (loc, actor));
2105 add_stmt (rdeflab);
2106 b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2107 b = coro_build_cvt_void_expr_stmt (b, loc);
2108 add_stmt (b);
2109
2110 lab_num = 2;
2111 /* The final resume should be made to hit the default (trap, UB) entry. */
2112 for (unsigned resu_pt = 0; resu_pt < body_count + 1; resu_pt++)
2113 {
2114 tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2115 b = build_case_label (l_num, NULL_TREE,
2116 create_anon_label_with_ctx (loc, actor));
2117 add_stmt (b);
2118 b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2119 l_num);
2120 b = coro_build_cvt_void_expr_stmt (b, loc);
2121 add_stmt (b);
2122 b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (rdeflab));
2123 add_stmt (b);
2124 lab_num += 2;
2125 }
2126
2127 /* Insert the prototype dispatcher. */
2128 finish_switch_stmt (dispatcher);
2129
2130 finish_if_stmt (lsb_if);
2131
2132 tree r = build_stmt (loc, LABEL_EXPR, actor_begin_label);
2133 add_stmt (r);
2134
2135 /* actor's version of the promise. */
2136 tree ap_m = lookup_member (coro_frame_type, get_identifier ("__p"), 1, 0,
2137 tf_warning_or_error);
2138 tree ap = build_class_member_access_expr (actor_frame, ap_m, NULL_TREE, false,
2139 tf_warning_or_error);
2140
2141 /* actor's coroutine 'self handle'. */
2142 tree ash_m = lookup_member (coro_frame_type, get_identifier ("__self_h"), 1,
2143 0, tf_warning_or_error);
2144 tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
2145 false, tf_warning_or_error);
2146 /* So construct the self-handle from the frame address. */
2147 tree hfa_m = lookup_member (handle_type, coro_from_address_identifier, 1,
2148 0, tf_warning_or_error);
2149
2150 r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
2151 vec<tree, va_gc> *args = make_tree_vector_single (r);
2152 tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
2153 NULL, tf_warning_or_error);
2154 r = build2 (INIT_EXPR, handle_type, ash, hfa);
2155 r = coro_build_cvt_void_expr_stmt (r, loc);
2156 add_stmt (r);
2157 release_tree_vector (args);
2158
2159 /* Now we know the real promise, and enough about the frame layout to
2160 decide where to put things. */
2161
2162 await_xform_data xform
2163 = {actor, actor_frame, promise_proxy, ap, self_h_proxy, ash};
2164
2165 /* Get a reference to the initial suspend var in the frame. */
2166 transform_await_expr (initial_await, &xform);
2167 tree initial_await_stmt = coro_build_expr_stmt (initial_await, loc);
2168
2169 /* co_return branches to the final_suspend label, so declare that now. */
2170 tree fs_label = create_named_label_with_ctx (loc, "final.suspend", actor);
2171
2172 /* Expand co_returns in the saved function body */
2173 fnbody = expand_co_returns (&fnbody, promise_proxy, ap, fs_label);
2174
2175 /* n4849 adds specific behaviour to treat exceptions thrown by the
2176 await_resume () of the initial suspend expression. In order to
2177 implement this, we need to treat the initial_suspend expression
2178 as if it were part of the user-authored function body. This
2179 only applies if exceptions are enabled. */
2180 if (flag_exceptions)
2181 {
2182 tree outer = fnbody;
2183 if (TREE_CODE (outer) == BIND_EXPR)
2184 outer = BIND_EXPR_BODY (outer);
2185 gcc_checking_assert (TREE_CODE (outer) == TRY_BLOCK);
2186 tree sl = TRY_STMTS (outer);
2187 if (TREE_CODE (sl) == STATEMENT_LIST)
2188 {
2189 tree_stmt_iterator si = tsi_start (sl);
2190 tsi_link_before (&si, initial_await_stmt, TSI_NEW_STMT);
2191 }
2192 else
2193 {
2194 tree new_try = NULL_TREE;
2195 append_to_statement_list (initial_await_stmt, &new_try);
2196 append_to_statement_list (sl, &new_try);
2197 TRY_STMTS (outer) = new_try;
2198 }
2199 }
2200 else
2201 add_stmt (initial_await_stmt);
2202
2203 /* Transform the await expressions in the function body. Only do each
2204 await tree once! */
2205 hash_set<tree> pset;
2206 cp_walk_tree (&fnbody, transform_await_wrapper, &xform, &pset);
2207
2208 /* Add in our function body with the co_returns rewritten to final form. */
2209 add_stmt (fnbody);
2210
2211 /* Final suspend starts here. */
2212 r = build_stmt (loc, LABEL_EXPR, fs_label);
2213 add_stmt (r);
2214
2215 /* Set the actor pointer to null, so that 'done' will work.
2216 Resume from here is UB anyway - although a 'ready' await will
2217 branch to the final resume, and fall through to the destroy. */
2218 tree resume_m
2219 = lookup_member (coro_frame_type, get_identifier ("__resume"),
2220 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2221 tree res_x = build_class_member_access_expr (actor_frame, resume_m, NULL_TREE,
2222 false, tf_warning_or_error);
2223 r = build1 (CONVERT_EXPR, act_des_fn_ptr, integer_zero_node);
2224 r = build2 (INIT_EXPR, act_des_fn_ptr, res_x, r);
2225 r = coro_build_cvt_void_expr_stmt (r, loc);
2226 add_stmt (r);
2227
2228 /* Get a reference to the final suspend var in the frame. */
2229 transform_await_expr (final_await, &xform);
2230 r = coro_build_expr_stmt (final_await, loc);
2231 add_stmt (r);
2232
2233 /* now do the tail of the function. */
2234 tree del_promise_label
2235 = create_named_label_with_ctx (loc, "coro.delete.promise", actor);
2236 r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2237 add_stmt (r);
2238
2239 /* Destructors for the things we built explicitly. */
2240 r = build_special_member_call (ap, complete_dtor_identifier, NULL,
2241 promise_type, LOOKUP_NORMAL,
2242 tf_warning_or_error);
2243 add_stmt (r);
2244
2245 tree del_frame_label
2246 = create_named_label_with_ctx (loc, "coro.delete.frame", actor);
2247 r = build_stmt (loc, LABEL_EXPR, del_frame_label);
2248 add_stmt (r);
2249
2250 /* Here deallocate the frame (if we allocated it), which we will have at
2251 present. */
2252 tree fnf_m
2253 = lookup_member (coro_frame_type, get_identifier ("__frame_needs_free"), 1,
2254 0, tf_warning_or_error);
2255 tree fnf2_x = build_class_member_access_expr (actor_frame, fnf_m, NULL_TREE,
2256 false, tf_warning_or_error);
2257
2258 tree need_free_if = begin_if_stmt ();
2259 fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x);
2260 tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node);
2261 finish_if_stmt_cond (cmp, need_free_if);
2262 if (param_dtor_list != NULL)
2263 {
2264 int i;
2265 tree pid;
2266 FOR_EACH_VEC_ELT (*param_dtor_list, i, pid)
2267 {
2268 tree m
2269 = lookup_member (coro_frame_type, pid, 1, 0, tf_warning_or_error);
2270 tree a = build_class_member_access_expr (actor_frame, m, NULL_TREE,
2271 false, tf_warning_or_error);
2272 tree t = TREE_TYPE (a);
2273 tree dtor;
2274 dtor
2275 = build_special_member_call (a, complete_dtor_identifier, NULL, t,
2276 LOOKUP_NORMAL, tf_warning_or_error);
2277 add_stmt (dtor);
2278 }
2279 }
2280
2281 /* n4849 [dcl.fct.def.coroutine] / 12
2282 The deallocation function’s name is looked up in the scope of the promise
2283 type. If this lookup fails, the deallocation function’s name is looked up
2284 in the global scope. If deallocation function lookup finds both a usual
2285 deallocation function with only a pointer parameter and a usual
2286 deallocation function with both a pointer parameter and a size parameter,
2287 then the selected deallocation function shall be the one with two
2288 parameters. Otherwise, the selected deallocation function shall be the
2289 function with one parameter. If no usual deallocation function is found
2290 the program is ill-formed. The selected deallocation function shall be
2291 called with the address of the block of storage to be reclaimed as its
2292 first argument. If a deallocation function with a parameter of type
2293 std::size_t is used, the size of the block is passed as the corresponding
2294 argument. */
2295
2296 tree del_coro_fr = NULL_TREE;
2297 tree frame_arg = build1 (CONVERT_EXPR, ptr_type_node, actor_fp);
2298
2299 tree delname = ovl_op_identifier (false, DELETE_EXPR);
2300 tree fns = lookup_promise_method (orig, delname, loc, /*musthave=*/false);
2301 if (fns && BASELINK_P (fns))
2302 {
2303 /* Look for sized version first, since this takes precedence. */
2304 vec<tree, va_gc> *args = make_tree_vector ();
2305 vec_safe_push (args, frame_arg);
2306 vec_safe_push (args, frame_size);
2307 tree dummy_promise = build_dummy_object (promise_type);
2308
2309 /* It's OK to fail for this one... */
2310 del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2311 NULL_TREE, LOOKUP_NORMAL, NULL,
2312 tf_none);
2313
2314 if (!del_coro_fr || del_coro_fr == error_mark_node)
2315 {
2316 release_tree_vector (args);
2317 args = make_tree_vector_single (frame_arg);
2318 del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2319 NULL_TREE, LOOKUP_NORMAL, NULL,
2320 tf_none);
2321 }
2322
2323 /* But one of them must succeed, or the program is ill-formed. */
2324 if (!del_coro_fr || del_coro_fr == error_mark_node)
2325 {
2326 error_at (loc, "%qE is provided by %qT but is not usable with"
2327 " the function signature %qD", delname, promise_type, orig);
2328 del_coro_fr = error_mark_node;
2329 }
2330 }
2331 else
2332 {
2333 del_coro_fr = build_op_delete_call (DELETE_EXPR, frame_arg, frame_size,
2334 /*global_p=*/true, /*placement=*/NULL,
2335 /*alloc_fn=*/NULL,
2336 tf_warning_or_error);
2337 if (!del_coro_fr || del_coro_fr == error_mark_node)
2338 del_coro_fr = error_mark_node;
2339 }
2340
2341 del_coro_fr = coro_build_cvt_void_expr_stmt (del_coro_fr, loc);
2342 add_stmt (del_coro_fr);
2343 finish_then_clause (need_free_if);
2344 tree scope = IF_SCOPE (need_free_if);
2345 IF_SCOPE (need_free_if) = NULL;
2346 r = do_poplevel (scope);
2347 add_stmt (r);
2348
2349 /* done. */
2350 r = build_stmt (loc, RETURN_EXPR, NULL);
2351 TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */
2352 r = maybe_cleanup_point_expr_void (r);
2353 add_stmt (r);
2354
2355 /* This is the suspend return point. */
2356 r = build_stmt (loc, LABEL_EXPR, ret_label);
2357 add_stmt (r);
2358
2359 r = build_stmt (loc, RETURN_EXPR, NULL);
2360 TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */
2361 r = maybe_cleanup_point_expr_void (r);
2362 add_stmt (r);
2363
2364 /* This is the 'continuation' return point. For such a case we have a coro
2365 handle (from the await_suspend() call) and we want handle.resume() to
2366 execute as a tailcall allowing arbitrary chaining of coroutines. */
2367 r = build_stmt (loc, LABEL_EXPR, continue_label);
2368 add_stmt (r);
2369
2370 /* We want to force a tail-call even for O0/1, so this expands the resume
2371 call into its underlying implementation. */
2372 tree addr = lookup_member (void_coro_handle_type, coro_address_identifier,
2373 1, 0, tf_warning_or_error);
2374 addr = build_new_method_call (continuation, addr, NULL, NULL_TREE,
2375 LOOKUP_NORMAL, NULL, tf_warning_or_error);
2376 tree resume = build_call_expr_loc
2377 (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
2378
2379 /* Now we have the actual call, and we can mark it as a tail. */
2380 CALL_EXPR_TAILCALL (resume) = true;
2381 /* ... and for optimisation levels 0..1, mark it as requiring a tail-call
2382 for correctness. It seems that doing this for optimisation levels that
2383 normally perform tail-calling, confuses the ME (or it would be logical
2384 to put this on unilaterally). */
2385 if (optimize < 2)
2386 CALL_EXPR_MUST_TAIL_CALL (resume) = true;
2387 resume = coro_build_cvt_void_expr_stmt (resume, loc);
2388 add_stmt (resume);
2389
2390 r = build_stmt (loc, RETURN_EXPR, NULL);
2391 gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
2392 add_stmt (r);
2393
2394 /* We will need to know which resume point number should be encoded. */
2395 tree res_idx_m
2396 = lookup_member (coro_frame_type, resume_idx_name,
2397 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2398 tree resume_pt_number
2399 = build_class_member_access_expr (actor_frame, res_idx_m, NULL_TREE, false,
2400 tf_warning_or_error);
2401
2402 /* Boolean value to flag that the initial suspend expression's
2403 await_resume () has been called, and therefore we are in the user's
2404 function body for the purposes of handing exceptions. */
2405 tree i_a_r_c_m
2406 = lookup_member (coro_frame_type, get_identifier ("__i_a_r_c"),
2407 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2408 tree i_a_r_c
2409 = build_class_member_access_expr (actor_frame, i_a_r_c_m, NULL_TREE,
2410 false, tf_warning_or_error);
2411
2412 /* We've now rewritten the tree and added the initial and final
2413 co_awaits. Now pass over the tree and expand the co_awaits. */
2414
2415 coro_aw_data data = {actor, actor_fp, resume_pt_number, i_a_r_c,
2416 ash, del_promise_label, ret_label,
2417 continue_label, continuation, 2};
2418 cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);
2419
2420 actor_body = pop_stmt_list (actor_body);
2421 BIND_EXPR_BODY (actor_bind) = actor_body;
2422
2423 finish_compound_stmt (stmt);
2424 DECL_SAVED_TREE (actor) = pop_stmt_list (actor_outer);
2425 verify_stmt_tree (DECL_SAVED_TREE (actor));
2426 }
2427
2428 /* The prototype 'destroy' function :
2429 frame->__resume_at |= 1;
2430 actor (frame); */
2431
2432 static void
2433 build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
2434 tree actor)
2435 {
2436 /* One param, the coro frame pointer. */
2437 tree destr_fp = DECL_ARGUMENTS (destroy);
2438
2439 /* A void return. */
2440 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
2441 DECL_ARTIFICIAL (resdecl) = 1;
2442 DECL_IGNORED_P (resdecl) = 1;
2443 DECL_RESULT (destroy) = resdecl;
2444
2445 /* We have a definition here. */
2446 TREE_STATIC (destroy) = 1;
2447 DECL_COROUTINE_P (destroy) = 1;
2448
2449 tree destr_outer = push_stmt_list ();
2450 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
2451 tree dstr_stmt = begin_compound_stmt (BCS_FN_BODY);
2452
2453 tree destr_frame = build1 (INDIRECT_REF, coro_frame_type, destr_fp);
2454
2455 tree resume_idx_name = get_identifier ("__resume_at");
2456 tree rat_field = lookup_member (coro_frame_type, resume_idx_name, 1, 0,
2457 tf_warning_or_error);
2458 tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, destr_frame,
2459 rat_field, NULL_TREE);
2460
2461 /* _resume_at |= 1 */
2462 tree dstr_idx = build2 (BIT_IOR_EXPR, short_unsigned_type_node, rat,
2463 build_int_cst (short_unsigned_type_node, 1));
2464 tree r = build2 (MODIFY_EXPR, short_unsigned_type_node, rat, dstr_idx);
2465 r = coro_build_cvt_void_expr_stmt (r, loc);
2466 add_stmt (r);
2467
2468 /* So .. call the actor .. */
2469 r = build_call_expr_loc (loc, actor, 1, destr_fp);
2470 r = coro_build_cvt_void_expr_stmt (r, loc);
2471 add_stmt (r);
2472
2473 /* done. */
2474 r = build_stmt (loc, RETURN_EXPR, NULL);
2475 r = maybe_cleanup_point_expr_void (r);
2476 add_stmt (r);
2477
2478 finish_compound_stmt (dstr_stmt);
2479 DECL_SAVED_TREE (destroy) = pop_stmt_list (destr_outer);
2480 }
2481
2482 /* Helper that returns an identifier for an appended extension to the
2483 current un-mangled function name. */
2484
2485 static tree
2486 get_fn_local_identifier (tree orig, const char *append)
2487 {
2488 /* Figure out the bits we need to generate names for the outlined things
2489 For consistency, this needs to behave the same way as
2490 ASM_FORMAT_PRIVATE_NAME does. */
2491 tree nm = DECL_NAME (orig);
2492 const char *sep, *pfx = "";
2493 #ifndef NO_DOT_IN_LABEL
2494 sep = ".";
2495 #else
2496 #ifndef NO_DOLLAR_IN_LABEL
2497 sep = "$";
2498 #else
2499 sep = "_";
2500 pfx = "__";
2501 #endif
2502 #endif
2503
2504 char *an;
2505 if (DECL_ASSEMBLER_NAME (orig))
2506 an = ACONCAT ((IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig)), sep, append,
2507 (char *) 0));
2508 else if (DECL_USE_TEMPLATE (orig) && DECL_TEMPLATE_INFO (orig)
2509 && DECL_TI_ARGS (orig))
2510 {
2511 tree tpl_args = DECL_TI_ARGS (orig);
2512 an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), (char *) 0));
2513 for (int i = 0; i < TREE_VEC_LENGTH (tpl_args); ++i)
2514 {
2515 tree typ = DECL_NAME (TYPE_NAME (TREE_VEC_ELT (tpl_args, i)));
2516 an = ACONCAT ((an, sep, IDENTIFIER_POINTER (typ), (char *) 0));
2517 }
2518 an = ACONCAT ((an, sep, append, (char *) 0));
2519 }
2520 else
2521 an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), sep, append, (char *) 0));
2522
2523 return get_identifier (an);
2524 }
2525
2526 static tree
2527 build_init_or_final_await (location_t loc, bool is_final)
2528 {
2529 tree suspend_alt = is_final ? coro_final_suspend_identifier
2530 : coro_initial_suspend_identifier;
2531 tree setup_meth = lookup_promise_method (current_function_decl, suspend_alt,
2532 loc, /*musthave=*/true);
2533 if (!setup_meth || setup_meth == error_mark_node)
2534 return error_mark_node;
2535
2536 tree s_fn = NULL_TREE;
2537 tree setup_call = build_new_method_call (
2538 get_coroutine_promise_proxy (current_function_decl), setup_meth, NULL,
2539 NULL_TREE, LOOKUP_NORMAL, &s_fn, tf_warning_or_error);
2540
2541 if (!s_fn || setup_call == error_mark_node)
2542 return error_mark_node;
2543
2544 /* So build the co_await for this */
2545 /* For initial/final suspends the call is "a" per [expr.await] 3.2. */
2546 return build_co_await (loc, setup_call, (is_final ? FINAL_SUSPEND_POINT
2547 : INITIAL_SUSPEND_POINT));
2548 }
2549
2550 /* Callback to record the essential data for each await point found in the
2551 function. */
2552
2553 static bool
2554 register_await_info (tree await_expr, tree aw_type, tree aw_nam)
2555 {
2556 bool seen;
2557 suspend_point_info &s
2558 = suspend_points->get_or_insert (await_expr, &seen);
2559 if (seen)
2560 {
2561 error_at (EXPR_LOCATION (await_expr), "duplicate info for %qE",
2562 await_expr);
2563 return false;
2564 }
2565 s.awaitable_type = aw_type;
2566 s.await_field_id = aw_nam;
2567 return true;
2568 }
2569
2570 /* Small helper for the repetitive task of adding a new field to the coro
2571 frame type. */
2572
2573 static tree
2574 coro_make_frame_entry (tree *field_list, const char *name, tree fld_type,
2575 location_t loc)
2576 {
2577 tree id = get_identifier (name);
2578 tree decl = build_decl (loc, FIELD_DECL, id, fld_type);
2579 DECL_CHAIN (decl) = *field_list;
2580 *field_list = decl;
2581 return id;
2582 }
2583
2584 /* This data set is used when analyzing statements for await expressions. */
2585 struct susp_frame_data
2586 {
2587 /* Function-wide. */
2588 tree *field_list; /* The current coroutine frame field list. */
2589 tree handle_type; /* The self-handle type for this coroutine. */
2590 vec<tree, va_gc> *block_stack; /* Track block scopes. */
2591 vec<tree, va_gc> *bind_stack; /* Track current bind expr. */
2592 unsigned await_number; /* Which await in the function. */
2593 unsigned condition_number; /* Which replaced condition in the fn. */
2594 /* Temporary values for one statement or expression being analyzed. */
2595 hash_set<tree> captured_temps; /* The suspend captured these temps. */
2596 vec<tree, va_gc> *to_replace; /* The VAR decls to replace. */
2597 unsigned saw_awaits; /* Count of awaits in this statement */
2598 bool captures_temporary; /* This expr captures temps by ref. */
2599 };
2600
2601 /* Walk the sub-tree looking for call expressions that both capture
2602 references and have compiler-temporaries as parms. */
2603
2604 static tree
2605 captures_temporary (tree *stmt, int *do_subtree, void *d)
2606 {
2607 /* Stop recursing if we see an await expression, the subtrees
2608 of that will be handled when it is processed. */
2609 if (TREE_CODE (*stmt) == CO_AWAIT_EXPR || TREE_CODE (*stmt) == CO_YIELD_EXPR)
2610 {
2611 *do_subtree = 0;
2612 return NULL_TREE;
2613 }
2614
2615 /* We're only interested in calls. */
2616 if (TREE_CODE (*stmt) != CALL_EXPR)
2617 return NULL_TREE;
2618
2619 /* Does this call capture references?
2620 Strip the ADDRESS_EXPR to get the fn decl and inspect it. */
2621 tree fn = TREE_OPERAND (CALL_EXPR_FN (*stmt), 0);
2622 bool is_meth = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
2623 tree arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2624 unsigned offset = 3;
2625 for (unsigned anum = 0; arg != NULL; arg = TREE_CHAIN (arg), anum++)
2626 {
2627 tree parm_type = TREE_VALUE (arg);
2628 if (anum == 0 && is_meth && INDIRECT_TYPE_P (parm_type))
2629 {
2630 /* Account for 'this' when the fn is a method. Unless it
2631 belongs to a CTOR or DTOR. */
2632 if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
2633 continue;
2634 }
2635 else if (!TYPE_REF_P (parm_type))
2636 /* If it's not a reference, we don't care. */
2637 continue;
2638
2639 /* Fetch the value presented to the fn. */
2640 tree parm = TREE_OPERAND (*stmt, anum + offset);
2641
2642 while (TREE_CODE (parm) == NOP_EXPR)
2643 parm = TREE_OPERAND (parm, 0);
2644
2645 /* We only care if we're taking the addr of a temporary. */
2646 if (TREE_CODE (parm) != ADDR_EXPR)
2647 continue;
2648
2649 parm = TREE_OPERAND (parm, 0);
2650
2651 /* In case of component_ref, we need to capture the object of base
2652 class as if it is temporary object. There are two possibilities:
2653 (*base).field and base->field. */
2654 while (TREE_CODE (parm) == COMPONENT_REF)
2655 {
2656 parm = TREE_OPERAND (parm, 0);
2657 if (TREE_CODE (parm) == INDIRECT_REF)
2658 parm = TREE_OPERAND (parm, 0);
2659 parm = STRIP_NOPS (parm);
2660 }
2661
2662 /* This isn't a temporary. */
2663 if ((TREE_CODE (parm) == VAR_DECL && !DECL_ARTIFICIAL (parm))
2664 || TREE_CODE (parm) == PARM_DECL
2665 || TREE_CODE (parm) == NON_LVALUE_EXPR)
2666 continue;
2667
2668 if (TREE_CODE (parm) == TARGET_EXPR)
2669 {
2670 /* We're taking the address of a temporary and using it as a ref. */
2671 tree tvar = TREE_OPERAND (parm, 0);
2672 gcc_checking_assert (DECL_ARTIFICIAL (tvar));
2673
2674 susp_frame_data *data = (susp_frame_data *) d;
2675 data->captures_temporary = true;
2676 /* Record this one so we don't duplicate, and on the first
2677 occurrence note the target expr to be replaced. */
2678 if (!data->captured_temps.add (tvar))
2679 vec_safe_push (data->to_replace, parm);
2680 /* Now see if the initializer contains any more cases. */
2681 hash_set<tree> visited;
2682 tree res = cp_walk_tree (&TREE_OPERAND (parm, 1),
2683 captures_temporary, d, &visited);
2684 if (res)
2685 return res;
2686 /* Otherwise, we're done with sub-trees for this. */
2687 }
2688 else if (TREE_CODE (parm) == CO_AWAIT_EXPR)
2689 {
2690 /* CO_AWAIT expressions behave in a similar manner to target
2691 expressions when the await_resume call is contained in one. */
2692 tree awr = TREE_OPERAND (parm, 3); /* call vector. */
2693 awr = TREE_VEC_ELT (awr, 2); /* resume call. */
2694 if (TREE_CODE (awr) == TARGET_EXPR)
2695 {
2696 tree tvar = TREE_OPERAND (awr, 0);
2697 gcc_checking_assert (DECL_ARTIFICIAL (tvar));
2698
2699 susp_frame_data *data = (susp_frame_data *) d;
2700 data->captures_temporary = true;
2701 /* Use this as a place-holder. */
2702 if (!data->captured_temps.add (tvar))
2703 vec_safe_push (data->to_replace, parm);
2704 }
2705 /* We will walk the sub-trees of this co_await separately. */
2706 }
2707 else
2708 gcc_unreachable ();
2709 }
2710 /* As far as it's necessary, we've walked the subtrees of the call
2711 expr. */
2712 *do_subtree = 0;
2713 return NULL_TREE;
2714 }
2715
2716 /* If this is an await, then register it and decide on what coro
2717 frame storage is needed.
2718 If this is a co_yield (which embeds an await), drop the yield
2719 and record the await (the yield was kept for diagnostics only). */
2720
2721 static tree
2722 register_awaits (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
2723 {
2724 susp_frame_data *data = (susp_frame_data *) d;
2725
2726 if (TREE_CODE (*stmt) != CO_AWAIT_EXPR && TREE_CODE (*stmt) != CO_YIELD_EXPR)
2727 return NULL_TREE;
2728
2729 tree aw_expr = *stmt;
2730 location_t aw_loc = EXPR_LOCATION (aw_expr); /* location of the co_xxxx. */
2731 /* co_yield is syntactic sugar, re-write it to co_await. */
2732 if (TREE_CODE (aw_expr) == CO_YIELD_EXPR)
2733 {
2734 aw_expr = TREE_OPERAND (aw_expr, 1);
2735 *stmt = aw_expr;
2736 }
2737
2738 /* If the awaitable is a parm or a local variable, then we already have
2739 a frame copy, so don't make a new one. */
2740 tree aw = TREE_OPERAND (aw_expr, 1);
2741 tree aw_field_type = TREE_TYPE (aw);
2742 tree aw_field_nam = NULL_TREE;
2743 if (INDIRECT_REF_P (aw))
2744 aw = TREE_OPERAND (aw, 0);
2745 if (TREE_CODE (aw) == PARM_DECL
2746 || (TREE_CODE (aw) == VAR_DECL && !DECL_ARTIFICIAL (aw)))
2747 ; /* Don't make an additional copy. */
2748 else
2749 {
2750 /* The required field has the same type as the proxy stored in the
2751 await expr. */
2752 char *nam = xasprintf ("__aw_s.%d", data->await_number);
2753 aw_field_nam = coro_make_frame_entry (data->field_list, nam,
2754 aw_field_type, aw_loc);
2755 free (nam);
2756 }
2757
2758 register_await_info (aw_expr, aw_field_type, aw_field_nam);
2759
2760 /* Count how many awaits the current expression contains. */
2761 data->saw_awaits++;
2762 /* Each await suspend context is unique, this is a function-wide value. */
2763 data->await_number++;
2764
2765 /* We now need to know if to take special action on lifetime extension
2766 of temporaries captured by reference. This can only happen if such
2767 a case appears in the initializer for the awaitable. The callback
2768 records captured temporaries including subtrees of initializers. */
2769 hash_set<tree> visited;
2770 tree res = cp_walk_tree (&TREE_OPERAND (aw_expr, 2), captures_temporary, d,
2771 &visited);
2772 return res;
2773 }
2774
2775 /* The gimplifier correctly extends the lifetime of temporaries captured
2776 by reference (per. [class.temporary] (6.9) "A temporary object bound
2777 to a reference parameter in a function call persists until the completion
2778 of the full-expression containing the call"). However, that is not
2779 sufficient to work across a suspension - and we need to promote such
2780 temporaries to be regular vars that will then get a coro frame slot.
2781 We don't want to incur the effort of checking for this unless we have
2782 an await expression in the current full expression. */
2783
2784 /* This takes the statement which contains one or more temporaries that have
2785 been 'captured' by reference in the initializer(s) of co_await(s).
2786 The statement is replaced by a bind expression that has actual variables
2787 to replace the temporaries. These variables will be added to the coro-
2788 frame in the same manner as user-authored ones. */
2789
2790 static void
2791 replace_statement_captures (tree *stmt, void *d)
2792 {
2793 susp_frame_data *awpts = (susp_frame_data *) d;
2794 location_t sloc = EXPR_LOCATION (*stmt);
2795 tree aw_bind
2796 = build3_loc (sloc, BIND_EXPR, void_type_node, NULL, NULL, NULL);
2797
2798 /* Any cleanup point expression might no longer be necessary, since we
2799 are removing one or more temporaries. */
2800 tree aw_statement_current = *stmt;
2801 if (TREE_CODE (aw_statement_current) == CLEANUP_POINT_EXPR)
2802 aw_statement_current = TREE_OPERAND (aw_statement_current, 0);
2803
2804 /* Collected the scope vars we need move the temps to regular. */
2805 tree aw_bind_body = push_stmt_list ();
2806 tree varlist = NULL_TREE;
2807 int vnum = -1;
2808 while (!awpts->to_replace->is_empty ())
2809 {
2810 tree to_replace = awpts->to_replace->pop ();
2811 tree orig_temp;
2812 if (TREE_CODE (to_replace) == CO_AWAIT_EXPR)
2813 {
2814 orig_temp = TREE_OPERAND (to_replace, 3);
2815 orig_temp = TREE_VEC_ELT (orig_temp, 2);
2816 orig_temp = TREE_OPERAND (orig_temp, 0);
2817 }
2818 else
2819 orig_temp = TREE_OPERAND (to_replace, 0);
2820
2821 tree var_type = TREE_TYPE (orig_temp);
2822 gcc_checking_assert (same_type_p (TREE_TYPE (to_replace), var_type));
2823 /* Build a variable to hold the captured value, this will be included
2824 in the frame along with any user-authored locals. */
2825 char *nam = xasprintf ("aw_%d.tmp.%d", awpts->await_number, ++vnum);
2826 tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
2827 free (nam);
2828 /* If we have better location than the whole expression use that, else
2829 fall back to the expression loc. */
2830 DECL_CONTEXT (newvar) = DECL_CONTEXT (orig_temp);
2831 if (DECL_SOURCE_LOCATION (orig_temp))
2832 sloc = DECL_SOURCE_LOCATION (orig_temp);
2833 else
2834 sloc = EXPR_LOCATION (*stmt);
2835 DECL_SOURCE_LOCATION (newvar) = sloc;
2836 DECL_CHAIN (newvar) = varlist;
2837 varlist = newvar; /* Chain it onto the list for the bind expr. */
2838 /* Declare and initialize it in the new bind scope. */
2839 add_decl_expr (newvar);
2840 tree new_s = build2_loc (sloc, INIT_EXPR, var_type, newvar, to_replace);
2841 new_s = coro_build_cvt_void_expr_stmt (new_s, sloc);
2842 add_stmt (new_s);
2843
2844 /* Replace all instances of that temp in the original expr. */
2845 proxy_replace pr = {to_replace, newvar};
2846 cp_walk_tree (&aw_statement_current, replace_proxy, &pr, NULL);
2847 }
2848
2849 /* What's left should be the original statement with any co_await captured
2850 temporaries broken out. Other temporaries might remain so see if we
2851 need to wrap the revised statement in a cleanup. */
2852 aw_statement_current = maybe_cleanup_point_expr_void (aw_statement_current);
2853 add_stmt (aw_statement_current);
2854
2855 BIND_EXPR_BODY (aw_bind) = pop_stmt_list (aw_bind_body);
2856 awpts->captured_temps.empty ();
2857
2858 BIND_EXPR_VARS (aw_bind) = nreverse (varlist);
2859 tree b_block = make_node (BLOCK);
2860 if (!awpts->block_stack->is_empty ())
2861 {
2862 tree s_block = awpts->block_stack->last ();
2863 if (s_block)
2864 {
2865 BLOCK_SUPERCONTEXT (b_block) = s_block;
2866 BLOCK_CHAIN (b_block) = BLOCK_SUBBLOCKS (s_block);
2867 BLOCK_SUBBLOCKS (s_block) = b_block;
2868 }
2869 }
2870 BIND_EXPR_BLOCK (aw_bind) = b_block;
2871 *stmt = aw_bind;
2872 }
2873
2874 /* This is called for single statements from the co-await statement walker.
2875 It checks to see if the statement contains any co-awaits and, if so,
2876 whether any of these 'capture' a temporary by reference. */
2877
2878 static tree
2879 maybe_promote_captured_temps (tree *stmt, void *d)
2880 {
2881 susp_frame_data *awpts = (susp_frame_data *) d;
2882 hash_set<tree> visited;
2883 awpts->saw_awaits = 0;
2884
2885 /* When register_awaits sees an await, it walks the initializer for
2886 that await looking for temporaries captured by reference and notes
2887 them in awpts->captured_temps. */
2888
2889 if (tree res = cp_walk_tree (stmt, register_awaits, d, &visited))
2890 return res; /* We saw some reason to abort the tree walk. */
2891
2892 /* We only need to take any action here if the statement contained any
2893 awaits and any of those had temporaries captured by reference in their
2894 initializers. */
2895
2896 if (awpts->saw_awaits > 0 && !awpts->captured_temps.is_empty ())
2897 replace_statement_captures (stmt, d);
2898
2899 return NULL_TREE;
2900 }
2901
2902 static tree
2903 await_statement_walker (tree *stmt, int *do_subtree, void *d)
2904 {
2905 tree res = NULL_TREE;
2906 susp_frame_data *awpts = (susp_frame_data *) d;
2907
2908 /* Process a statement at a time. */
2909 if (TREE_CODE (*stmt) == BIND_EXPR)
2910 {
2911 /* We might need to insert a new bind expression, and want to link it
2912 into the correct scope, so keep a note of the current block scope. */
2913 tree blk = BIND_EXPR_BLOCK (*stmt);
2914 vec_safe_push (awpts->block_stack, blk);
2915 res = cp_walk_tree (&BIND_EXPR_BODY (*stmt), await_statement_walker,
2916 d, NULL);
2917 awpts->block_stack->pop ();
2918 *do_subtree = 0; /* Done subtrees. */
2919 }
2920 else if (TREE_CODE (*stmt) == STATEMENT_LIST)
2921 {
2922 tree_stmt_iterator i;
2923 for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i))
2924 {
2925 res = cp_walk_tree (tsi_stmt_ptr (i), await_statement_walker,
2926 d, NULL);
2927 if (res)
2928 return res;
2929 }
2930 *do_subtree = 0; /* Done subtrees. */
2931 }
2932 else if (STATEMENT_CLASS_P (*stmt))
2933 return NULL_TREE; /* Process the subtrees. */
2934 else if (EXPR_P (*stmt))
2935 {
2936 res = maybe_promote_captured_temps (stmt, d);
2937 *do_subtree = 0; /* Done subtrees. */
2938 }
2939
2940 /* Continue recursion, if needed. */
2941 return res;
2942 }
2943
2944 /* For figuring out what param usage we have. */
2945
2946 struct param_frame_data
2947 {
2948 tree *field_list;
2949 hash_map<tree, param_info> *param_uses;
2950 hash_set<tree *> *visited;
2951 location_t loc;
2952 bool param_seen;
2953 };
2954
2955 static tree
2956 register_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
2957 {
2958 param_frame_data *data = (param_frame_data *) d;
2959
2960 /* For lambda closure content, we have to look specifically. */
2961 if (TREE_CODE (*stmt) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*stmt))
2962 {
2963 tree t = DECL_VALUE_EXPR (*stmt);
2964 return cp_walk_tree (&t, register_param_uses, d, NULL);
2965 }
2966
2967 if (TREE_CODE (*stmt) != PARM_DECL)
2968 return NULL_TREE;
2969
2970 /* If we already saw the containing expression, then we're done. */
2971 if (data->visited->add (stmt))
2972 return NULL_TREE;
2973
2974 bool existed;
2975 param_info &parm = data->param_uses->get_or_insert (*stmt, &existed);
2976 gcc_checking_assert (existed);
2977
2978 if (!parm.body_uses)
2979 {
2980 vec_alloc (parm.body_uses, 4);
2981 parm.body_uses->quick_push (stmt);
2982 data->param_seen = true;
2983 }
2984 else
2985 parm.body_uses->safe_push (stmt);
2986
2987 return NULL_TREE;
2988 }
2989
2990 /* For figuring out what local variable usage we have. */
2991
2992 struct local_vars_frame_data
2993 {
2994 tree *field_list;
2995 hash_map<tree, local_var_info> *local_var_uses;
2996 unsigned int nest_depth, bind_indx;
2997 location_t loc;
2998 bool saw_capture;
2999 bool local_var_seen;
3000 };
3001
3002 static tree
3003 register_local_var_uses (tree *stmt, int *do_subtree, void *d)
3004 {
3005 local_vars_frame_data *lvd = (local_vars_frame_data *) d;
3006
3007 /* As we enter a bind expression - record the vars there and then recurse.
3008 As we exit drop the nest depth.
3009 The bind index is a growing count of how many bind indices we've seen.
3010 We build a space in the frame for each local var. */
3011
3012 if (TREE_CODE (*stmt) == BIND_EXPR)
3013 {
3014 lvd->bind_indx++;
3015 lvd->nest_depth++;
3016 tree lvar;
3017 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
3018 lvar = DECL_CHAIN (lvar))
3019 {
3020 bool existed;
3021 local_var_info &local_var
3022 = lvd->local_var_uses->get_or_insert (lvar, &existed);
3023 gcc_checking_assert (!existed);
3024 local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
3025 tree lvtype = TREE_TYPE (lvar);
3026 local_var.frame_type = lvtype;
3027 local_var.field_idx = local_var.field_id = NULL_TREE;
3028 lvd->local_var_seen = true;
3029 /* If this var is a lambda capture proxy, we want to leave it alone,
3030 and later rewrite the DECL_VALUE_EXPR to indirect through the
3031 frame copy of the pointer to the lambda closure object. */
3032 local_var.is_lambda_capture = is_capture_proxy (lvar);
3033 if (local_var.is_lambda_capture)
3034 continue;
3035
3036 /* Make names depth+index unique, so that we can support nested
3037 scopes with identically named locals. */
3038 tree lvname = DECL_NAME (lvar);
3039 char *buf;
3040 if (lvname != NULL_TREE)
3041 buf = xasprintf ("__lv.%u.%u.%s", lvd->bind_indx, lvd->nest_depth,
3042 IDENTIFIER_POINTER (lvname));
3043 else
3044 buf = xasprintf ("__lv.%u.%u.D%u", lvd->bind_indx, lvd->nest_depth,
3045 DECL_UID (lvar));
3046 /* TODO: Figure out if we should build a local type that has any
3047 excess alignment or size from the original decl. */
3048 local_var.field_id
3049 = coro_make_frame_entry (lvd->field_list, buf, lvtype, lvd->loc);
3050 free (buf);
3051 /* We don't walk any of the local var sub-trees, they won't contain
3052 any bind exprs. */
3053 }
3054 cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
3055 *do_subtree = 0; /* We've done this. */
3056 lvd->nest_depth--;
3057 }
3058 return NULL_TREE;
3059 }
3060
3061 /* Build, return FUNCTION_DECL node with its coroutine frame pointer argument
3062 for either actor or destroy functions. */
3063
3064 static tree
3065 act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name)
3066 {
3067 tree fn_name = get_fn_local_identifier (orig, name);
3068 tree fn = build_lang_decl (FUNCTION_DECL, fn_name, fn_type);
3069 DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
3070 DECL_INITIAL (fn) = error_mark_node;
3071 tree id = get_identifier ("frame_ptr");
3072 tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
3073 DECL_CONTEXT (fp) = fn;
3074 DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
3075 DECL_ARGUMENTS (fn) = fp;
3076 return fn;
3077 }
3078
3079 /* Here we:
3080 a) Check that the function and promise type are valid for a
3081 coroutine.
3082 b) Carry out the initial morph to create the skeleton of the
3083 coroutine ramp function and the rewritten body.
3084
3085 Assumptions.
3086
3087 1. We only hit this code once all dependencies are resolved.
3088 2. The function body will be either a bind expr or a statement list
3089 3. That cfun and current_function_decl are valid for the case we're
3090 expanding.
3091 4. 'input_location' will be of the final brace for the function.
3092
3093 We do something like this:
3094 declare a dummy coro frame.
3095 struct _R_frame {
3096 using handle_type = coro::coroutine_handle<coro1::promise_type>;
3097 void (*__resume)(_R_frame *);
3098 void (*__destroy)(_R_frame *);
3099 coro1::promise_type __p;
3100 bool frame_needs_free; free the coro frame mem if set.
3101 bool i_a_r_c; [dcl.fct.def.coroutine] / 5.3
3102 short __resume_at;
3103 handle_type self_handle;
3104 (maybe) parameter copies.
3105 coro1::suspend_never_prt __is;
3106 coro1::suspend_always_prt __fs;
3107 (maybe) local variables saved
3108 (maybe) trailing space.
3109 }; */
3110
3111 bool
3112 morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
3113 {
3114 gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL);
3115
3116 if (!coro_function_valid_p (orig))
3117 return false;
3118
3119 /* The ramp function does return a value. */
3120 current_function_returns_value = 1;
3121
3122 /* We can't validly get here with an empty statement list, since there's no
3123 way for the FE to decide it's a coroutine in the absence of any code. */
3124 tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
3125 if (fnbody == NULL_TREE)
3126 return false;
3127
3128 /* We don't have the locus of the opening brace - it's filled in later (and
3129 there doesn't really seem to be any easy way to get at it).
3130 The closing brace is assumed to be input_location. */
3131 location_t fn_start = DECL_SOURCE_LOCATION (orig);
3132 gcc_rich_location fn_start_loc (fn_start);
3133
3134 /* Initial processing of the function-body.
3135 If we have no expressions or just an error then punt. */
3136 tree body_start = expr_first (fnbody);
3137 if (body_start == NULL_TREE || body_start == error_mark_node)
3138 {
3139 DECL_SAVED_TREE (orig) = push_stmt_list ();
3140 append_to_statement_list (DECL_SAVED_TREE (orig), &fnbody);
3141 return false;
3142 }
3143
3144 /* So, we've tied off the original body. Now start the replacement.
3145 If we encounter a fatal error we might return a now-empty body.
3146 TODO: determine if it would help to restore the original.
3147 determine if looking for more errors in coro_function_valid_p()
3148 and stashing types is a better solution. */
3149
3150 tree newbody = push_stmt_list ();
3151 DECL_SAVED_TREE (orig) = newbody;
3152
3153 /* If our original body is noexcept, then that's what we apply to our
3154 generated functions. Remember that we're NOEXCEPT and fish out the
3155 contained list (we tied off to the top level already). */
3156 bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
3157 if (is_noexcept)
3158 {
3159 /* Simplified abstract from begin_eh_spec_block, since we already
3160 know the outcome. */
3161 fnbody = TREE_OPERAND (body_start, 0); /* Stash the original... */
3162 add_stmt (body_start); /* ... and start the new. */
3163 TREE_OPERAND (body_start, 0) = push_stmt_list ();
3164 }
3165
3166 /* Create the coro frame type, as far as it can be known at this stage.
3167 1. Types we already know. */
3168
3169 tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
3170 gcc_assert (!VOID_TYPE_P (fn_return_type));
3171 tree handle_type = get_coroutine_handle_type (orig);
3172 tree promise_type = get_coroutine_promise_type (orig);
3173
3174 /* 2. Types we need to define or look up. */
3175
3176 /* We need to know, and inspect, each suspend point in the function
3177 in several places. It's convenient to place this map out of line
3178 since it's used from tree walk callbacks. */
3179 suspend_points = new hash_map<tree, suspend_point_info>;
3180
3181 /* Initial and final suspend types are special in that the co_awaits for
3182 them are synthetic. We need to find the type for each awaiter from
3183 the coroutine promise. */
3184 tree initial_await = build_init_or_final_await (fn_start, false);
3185 if (initial_await == error_mark_node)
3186 return false;
3187 /* The type of the frame var for this is the type of its temp proxy. */
3188 tree initial_suspend_type = TREE_TYPE (TREE_OPERAND (initial_await, 1));
3189
3190 tree final_await = build_init_or_final_await (fn_start, true);
3191 if (final_await == error_mark_node)
3192 return false;
3193
3194 /* The type of the frame var for this is the type of its temp proxy. */
3195 tree final_suspend_type = TREE_TYPE (TREE_OPERAND (final_await, 1));
3196
3197 tree fr_name = get_fn_local_identifier (orig, "frame");
3198 tree coro_frame_type = xref_tag (record_type, fr_name, ts_current, false);
3199 DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope ();
3200 tree coro_frame_ptr = build_pointer_type (coro_frame_type);
3201 tree act_des_fn_type
3202 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
3203 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
3204
3205 /* Declare the actor and destroyer function. */
3206 tree actor = act_des_fn (orig, act_des_fn_type, coro_frame_ptr, "actor");
3207 tree destroy = act_des_fn (orig, act_des_fn_type, coro_frame_ptr, "destroy");
3208
3209 /* Build our dummy coro frame layout. */
3210 coro_frame_type = begin_class_definition (coro_frame_type);
3211
3212 tree field_list = NULL_TREE;
3213 tree resume_name
3214 = coro_make_frame_entry (&field_list, "__resume", act_des_fn_ptr, fn_start);
3215 tree destroy_name = coro_make_frame_entry (&field_list, "__destroy",
3216 act_des_fn_ptr, fn_start);
3217 tree promise_name
3218 = coro_make_frame_entry (&field_list, "__p", promise_type, fn_start);
3219 tree fnf_name = coro_make_frame_entry (&field_list, "__frame_needs_free",
3220 boolean_type_node, fn_start);
3221 tree iarc_name = coro_make_frame_entry (&field_list, "__i_a_r_c",
3222 boolean_type_node, fn_start);
3223 tree resume_idx_name
3224 = coro_make_frame_entry (&field_list, "__resume_at",
3225 short_unsigned_type_node, fn_start);
3226
3227 /* We need a handle to this coroutine, which is passed to every
3228 await_suspend(). There's no point in creating it over and over. */
3229 (void) coro_make_frame_entry (&field_list, "__self_h", handle_type, fn_start);
3230
3231 /* Now add in fields for function params (if there are any).
3232 We do not attempt elision of copies at this stage, we do analyse the
3233 uses and build worklists to replace those when the state machine is
3234 lowered. */
3235
3236 hash_map<tree, param_info> *param_uses = NULL;
3237 if (DECL_ARGUMENTS (orig))
3238 {
3239 /* Build a hash map with an entry for each param.
3240 The key is the param tree.
3241 Then we have an entry for the frame field name.
3242 Then a cache for the field ref when we come to use it.
3243 Then a tree list of the uses.
3244 The second two entries start out empty - and only get populated
3245 when we see uses. */
3246 param_uses = new hash_map<tree, param_info>;
3247
3248 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3249 arg = DECL_CHAIN (arg))
3250 {
3251 bool existed;
3252 param_info &parm = param_uses->get_or_insert (arg, &existed);
3253 gcc_checking_assert (!existed);
3254 parm.body_uses = NULL;
3255 tree actual_type = TREE_TYPE (arg);
3256 actual_type = complete_type_or_else (actual_type, orig);
3257 if (actual_type == NULL_TREE)
3258 actual_type = error_mark_node;
3259 parm.orig_type = actual_type;
3260 parm.by_ref = parm.rv_ref = parm.pt_ref = false;
3261 if (TREE_CODE (actual_type) == REFERENCE_TYPE
3262 && TYPE_REF_IS_RVALUE (DECL_ARG_TYPE (arg)))
3263 {
3264 parm.rv_ref = true;
3265 actual_type = TREE_TYPE (actual_type);
3266 parm.frame_type = actual_type;
3267 }
3268 else if (TREE_CODE (actual_type) == REFERENCE_TYPE)
3269 {
3270 /* If the user passes by reference, then we will save the
3271 pointer to the original. As noted in
3272 [dcl.fct.def.coroutine] / 13, if the lifetime of the
3273 referenced item ends and then the coroutine is resumed,
3274 we have UB; well, the user asked for it. */
3275 actual_type = build_pointer_type (TREE_TYPE (actual_type));
3276 parm.frame_type = actual_type;
3277 parm.pt_ref = true;
3278 }
3279 else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
3280 {
3281 parm.by_ref = true;
3282 parm.frame_type = actual_type;
3283 }
3284 else
3285 parm.frame_type = actual_type;
3286
3287 parm.trivial_dtor = TYPE_HAS_TRIVIAL_DESTRUCTOR (parm.frame_type);
3288 tree pname = DECL_NAME (arg);
3289 char *buf = xasprintf ("__parm.%s", IDENTIFIER_POINTER (pname));
3290 parm.field_id = coro_make_frame_entry
3291 (&field_list, buf, actual_type, DECL_SOURCE_LOCATION (arg));
3292 free (buf);
3293 }
3294
3295 /* We want to record every instance of param's use, so don't include
3296 a 'visited' hash_set on the tree walk, but only record a containing
3297 expression once. */
3298 hash_set<tree *> visited;
3299 param_frame_data param_data
3300 = {&field_list, param_uses, &visited, fn_start, false};
3301 cp_walk_tree (&fnbody, register_param_uses, &param_data, NULL);
3302 }
3303
3304 /* Initial suspend is mandated. */
3305 tree init_susp_name = coro_make_frame_entry (&field_list, "__aw_s.is",
3306 initial_suspend_type, fn_start);
3307
3308 register_await_info (initial_await, initial_suspend_type, init_susp_name);
3309
3310 /* Now insert the data for any body await points, at this time we also need
3311 to promote any temporaries that are captured by reference (to regular
3312 vars) they will get added to the coro frame along with other locals. */
3313 susp_frame_data body_aw_points
3314 = {&field_list, handle_type, NULL, NULL, 0, 0,
3315 hash_set<tree> (), NULL, 0, false};
3316 body_aw_points.block_stack = make_tree_vector ();
3317 body_aw_points.bind_stack = make_tree_vector ();
3318 body_aw_points.to_replace = make_tree_vector ();
3319 cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);
3320
3321 /* Final suspend is mandated. */
3322 tree fin_susp_name = coro_make_frame_entry (&field_list, "__aw_s.fs",
3323 final_suspend_type, fn_start);
3324
3325 register_await_info (final_await, final_suspend_type, fin_susp_name);
3326
3327 /* 4. Now make space for local vars, this is conservative again, and we
3328 would expect to delete unused entries later. */
3329 hash_map<tree, local_var_info> local_var_uses;
3330 local_vars_frame_data local_vars_data
3331 = {&field_list, &local_var_uses, 0, 0, fn_start, false, false};
3332 cp_walk_tree (&fnbody, register_local_var_uses, &local_vars_data, NULL);
3333
3334 /* Tie off the struct for now, so that we can build offsets to the
3335 known entries. */
3336 TYPE_FIELDS (coro_frame_type) = field_list;
3337 TYPE_BINFO (coro_frame_type) = make_tree_binfo (0);
3338 BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node;
3339 BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type;
3340
3341 coro_frame_type = finish_struct (coro_frame_type, NULL_TREE);
3342
3343 /* Ramp: */
3344 /* Now build the ramp function pieces. */
3345 tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3346 add_stmt (ramp_bind);
3347 tree ramp_body = push_stmt_list ();
3348 tree empty_list = build_empty_stmt (fn_start);
3349
3350 tree coro_fp = build_lang_decl (VAR_DECL, get_identifier ("coro.frameptr"),
3351 coro_frame_ptr);
3352 tree varlist = coro_fp;
3353
3354 /* Collected the scope vars we need ... only one for now. */
3355 BIND_EXPR_VARS (ramp_bind) = nreverse (varlist);
3356
3357 /* We're now going to create a new top level scope block for the ramp
3358 function. */
3359 tree top_block = make_node (BLOCK);
3360
3361 BIND_EXPR_BLOCK (ramp_bind) = top_block;
3362 BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind);
3363 BLOCK_SUBBLOCKS (top_block) = NULL_TREE;
3364
3365 /* The decl_expr for the coro frame pointer, initialize to zero so that we
3366 can pass it to the IFN_CO_FRAME (since there's no way to pass a type,
3367 directly apparently). This avoids a "used uninitialized" warning. */
3368 tree r = build_stmt (fn_start, DECL_EXPR, coro_fp);
3369 tree zeroinit = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
3370 r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, zeroinit);
3371 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3372 add_stmt (r);
3373
3374 /* The CO_FRAME internal function is a mechanism to allow the middle end
3375 to adjust the allocation in response to optimisations. We provide the
3376 current conservative estimate of the frame size (as per the current)
3377 computed layout. */
3378 tree frame_size = TYPE_SIZE_UNIT (coro_frame_type);
3379 tree resizeable
3380 = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2,
3381 frame_size, coro_fp);
3382
3383 /* n4849 [dcl.fct.def.coroutine] / 10 (part1)
3384 The unqualified-id get_return_object_on_allocation_failure is looked up
3385 in the scope of the promise type by class member access lookup. */
3386
3387 tree grooaf_meth
3388 = lookup_promise_method (orig, coro_gro_on_allocation_fail_identifier,
3389 fn_start, /*musthave=*/false);
3390
3391 tree grooaf = NULL_TREE;
3392 tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig));
3393
3394 /* We don't require this, so lookup_promise_method can return NULL... */
3395 if (grooaf_meth && BASELINK_P (grooaf_meth))
3396 {
3397 /* ... but, if the lookup succeeds, then the function must be
3398 usable.
3399 build_new_method_call () wants a valid pointer to (an empty) args
3400 list in this case. */
3401 vec<tree, va_gc> *args = make_tree_vector ();
3402 grooaf = build_new_method_call (dummy_promise, grooaf_meth, &args,
3403 NULL_TREE, LOOKUP_NORMAL, NULL,
3404 tf_warning_or_error);
3405 release_tree_vector (args);
3406 }
3407
3408 /* Allocate the frame, this has several possibilities:
3409 n4849 [dcl.fct.def.coroutine] / 9 (part 1)
3410 The allocation function’s name is looked up in the scope of the promise
3411 type. It's not a failure for it to be absent see part 4, below. */
3412 tree nwname = ovl_op_identifier (false, NEW_EXPR);
3413 tree fns = lookup_promise_method (orig, nwname, fn_start,
3414 /*musthave=*/false);
3415 tree new_fn = NULL_TREE;
3416 if (fns && BASELINK_P (fns))
3417 {
3418 /* n4849 [dcl.fct.def.coroutine] / 9 (part 2)
3419 If the lookup finds an allocation function in the scope of the promise
3420 type, overload resolution is performed on a function call created by
3421 assembling an argument list. The first argument is the amount of space
3422 requested, and has type std::size_t. The succeeding arguments are
3423 those of the original function. */
3424 vec<tree, va_gc> *args = make_tree_vector ();
3425 vec_safe_push (args, resizeable); /* Space needed. */
3426 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3427 arg = DECL_CHAIN (arg))
3428 vec_safe_push (args, arg);
3429
3430 /* We might need to check that the provided function is nothrow. */
3431 tree func;
3432 /* Failure is OK for the first attempt. */
3433 new_fn = build_new_method_call (dummy_promise, fns, &args, NULL,
3434 LOOKUP_NORMAL, &func, tf_none);
3435 release_tree_vector (args);
3436
3437 if (!new_fn || new_fn == error_mark_node)
3438 {
3439 /* n4849 [dcl.fct.def.coroutine] / 9 (part 3)
3440 If no viable function is found, overload resolution is performed
3441 again on a function call created by passing just the amount of
3442 space required as an argument of type std::size_t. */
3443 args = make_tree_vector ();
3444 vec_safe_push (args, resizeable); /* Space needed. */
3445 new_fn = build_new_method_call (dummy_promise, fns, &args,
3446 NULL_TREE, LOOKUP_NORMAL, &func,
3447 tf_none);
3448 release_tree_vector (args);
3449 }
3450
3451 /* However, if the initial lookup succeeded, then one of these two
3452 options must be available. */
3453 if (!new_fn || new_fn == error_mark_node)
3454 {
3455 error_at (fn_start, "%qE is provided by %qT but is not usable with"
3456 " the function signature %qD", nwname, promise_type, orig);
3457 new_fn = error_mark_node;
3458 }
3459 else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func)))
3460 error_at (fn_start, "%qE is provided by %qT but %qE is not marked"
3461 " %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname);
3462 }
3463 else
3464 {
3465 /* n4849 [dcl.fct.def.coroutine] / 9 (part 4)
3466 If this lookup fails, the allocation function’s name is looked up in
3467 the global scope. */
3468
3469 vec<tree, va_gc> *args;
3470 /* build_operator_new_call () will insert size needed as element 0 of
3471 this, and we might need to append the std::nothrow constant. */
3472 vec_alloc (args, 2);
3473
3474 if (grooaf)
3475 {
3476 /* n4849 [dcl.fct.def.coroutine] / 10 (part 2)
3477 If any declarations (of the get return on allocation fail) are
3478 found, then the result of a call to an allocation function used
3479 to obtain storage for the coroutine state is assumed to return
3480 nullptr if it fails to obtain storage and, if a global allocation
3481 function is selected, the ::operator new(size_t, nothrow_t) form
3482 is used. The allocation function used in this case shall have a
3483 non-throwing noexcept-specification. So we need std::nothrow. */
3484 tree std_nt = lookup_qualified_name (std_node,
3485 get_identifier ("nothrow"),
3486 0, /*complain=*/true, false);
3487 vec_safe_push (args, std_nt);
3488 }
3489
3490 /* If we get to this point, we must succeed in looking up the global
3491 operator new for the params provided. Extract a simplified version
3492 of the machinery from build_operator_new_call. This can update the
3493 frame size. */
3494 tree cookie = NULL;
3495 new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie,
3496 /*align_arg=*/NULL,
3497 /*size_check=*/NULL, /*fn=*/NULL,
3498 tf_warning_or_error);
3499 resizeable = build_call_expr_internal_loc
3500 (fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp);
3501 CALL_EXPR_ARG (new_fn, 0) = resizeable;
3502
3503 release_tree_vector (args);
3504 }
3505
3506 tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn);
3507 r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, allocated);
3508 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3509 add_stmt (r);
3510
3511 /* If the user provided a method to return an object on alloc fail, then
3512 check the returned pointer and call the func if it's null.
3513 Otherwise, no check, and we fail for noexcept/fno-exceptions cases. */
3514
3515 if (grooaf)
3516 {
3517 /* n4849 [dcl.fct.def.coroutine] / 10 (part 3)
3518 If the allocation function returns nullptr,the coroutine returns
3519 control to the caller of the coroutine and the return value is
3520 obtained by a call to T::get_return_object_on_allocation_failure(),
3521 where T is the promise type. */
3522 tree cfra_label
3523 = create_named_label_with_ctx (fn_start, "coro.frame.active",
3524 current_scope ());
3525 tree early_ret_list = NULL;
3526 /* init the retval using the user's func. */
3527 r = build2 (INIT_EXPR, TREE_TYPE (DECL_RESULT (orig)), DECL_RESULT (orig),
3528 grooaf);
3529 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3530 append_to_statement_list (r, &early_ret_list);
3531 /* We know it's the correct type. */
3532 r = DECL_RESULT (orig);
3533 r = build_stmt (fn_start, RETURN_EXPR, r);
3534 TREE_NO_WARNING (r) |= 1;
3535 r = maybe_cleanup_point_expr_void (r);
3536 append_to_statement_list (r, &early_ret_list);
3537
3538 tree goto_st = NULL;
3539 r = build1 (GOTO_EXPR, void_type_node, cfra_label);
3540 append_to_statement_list (r, &goto_st);
3541
3542 tree ckk = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
3543 tree ckz = build2 (EQ_EXPR, boolean_type_node, coro_fp, ckk);
3544 r = build3 (COND_EXPR, void_type_node, ckz, early_ret_list, empty_list);
3545 add_stmt (r);
3546
3547 cfra_label = build_stmt (fn_start, LABEL_EXPR, cfra_label);
3548 add_stmt (cfra_label);
3549 }
3550
3551 /* deref the frame pointer, to use in member access code. */
3552 tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error);
3553
3554 /* For now, once allocation has succeeded we always assume that this needs
3555 destruction, there's no impl. for frame allocation elision. */
3556 tree fnf_m
3557 = lookup_member (coro_frame_type, fnf_name, 1, 0, tf_warning_or_error);
3558 tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE,
3559 false, tf_warning_or_error);
3560 r = build2 (INIT_EXPR, boolean_type_node, fnf_x, boolean_true_node);
3561 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3562 add_stmt (r);
3563
3564 /* Put the resumer and destroyer functions in. */
3565
3566 tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor);
3567 tree resume_m
3568 = lookup_member (coro_frame_type, resume_name,
3569 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3570 tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE,
3571 false, tf_warning_or_error);
3572 r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, resume_x, actor_addr);
3573 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3574 add_stmt (r);
3575
3576 tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy);
3577 tree destroy_m
3578 = lookup_member (coro_frame_type, destroy_name,
3579 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3580 tree destroy_x
3581 = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false,
3582 tf_warning_or_error);
3583 r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, destroy_x, destroy_addr);
3584 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3585 add_stmt (r);
3586
3587 /* n4849 [dcl.fct.def.coroutine] /13
3588 When a coroutine is invoked, a copy is created for each coroutine
3589 parameter. Each such copy is an object with automatic storage duration
3590 that is direct-initialized from an lvalue referring to the corresponding
3591 parameter if the parameter is an lvalue reference, and from an xvalue
3592 referring to it otherwise. A reference to a parameter in the function-
3593 body of the coroutine and in the call to the coroutine promise
3594 constructor is replaced by a reference to its copy. */
3595
3596 vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs. */
3597
3598 /* The initialization and destruction of each parameter copy occurs in the
3599 context of the called coroutine. Initializations of parameter copies are
3600 sequenced before the call to the coroutine promise constructor and
3601 indeterminately sequenced with respect to each other. The lifetime of
3602 parameter copies ends immediately after the lifetime of the coroutine
3603 promise object ends. */
3604
3605 vec<tree, va_gc> *param_dtor_list = NULL;
3606
3607 if (DECL_ARGUMENTS (orig))
3608 {
3609 promise_args = make_tree_vector ();
3610 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3611 arg = DECL_CHAIN (arg))
3612 {
3613 bool existed;
3614 param_info &parm = param_uses->get_or_insert (arg, &existed);
3615
3616 tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
3617 /*protect=*/1, /*want_type=*/0,
3618 tf_warning_or_error);
3619 tree fld_idx
3620 = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE,
3621 false, tf_warning_or_error);
3622
3623 /* Add this to the promise CTOR arguments list, accounting for
3624 refs. */
3625 if (parm.by_ref)
3626 vec_safe_push (promise_args, fld_idx);
3627 else if (parm.rv_ref)
3628 vec_safe_push (promise_args, rvalue (fld_idx));
3629 else
3630 vec_safe_push (promise_args, arg);
3631
3632 if (TYPE_NEEDS_CONSTRUCTING (parm.frame_type))
3633 {
3634 vec<tree, va_gc> *p_in;
3635 if (parm.by_ref
3636 && classtype_has_non_deleted_move_ctor (parm.frame_type)
3637 && !classtype_has_non_deleted_copy_ctor (parm.frame_type))
3638 p_in = make_tree_vector_single (rvalue (arg));
3639 else
3640 p_in = make_tree_vector_single (arg);
3641 /* Construct in place or move as relevant. */
3642 r = build_special_member_call (fld_idx, complete_ctor_identifier,
3643 &p_in, parm.frame_type,
3644 LOOKUP_NORMAL,
3645 tf_warning_or_error);
3646 release_tree_vector (p_in);
3647 }
3648 else
3649 {
3650 if (parm.rv_ref)
3651 r = convert_from_reference (arg);
3652 else if (!same_type_p (parm.frame_type, DECL_ARG_TYPE (arg)))
3653 r = build1_loc (DECL_SOURCE_LOCATION (arg), CONVERT_EXPR,
3654 parm.frame_type, arg);
3655 else
3656 r = arg;
3657 r = build_modify_expr (fn_start, fld_idx, parm.frame_type,
3658 INIT_EXPR, DECL_SOURCE_LOCATION (arg), r,
3659 TREE_TYPE (r));
3660 }
3661 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3662 add_stmt (r);
3663 if (!parm.trivial_dtor)
3664 {
3665 if (param_dtor_list == NULL)
3666 param_dtor_list = make_tree_vector ();
3667 vec_safe_push (param_dtor_list, parm.field_id);
3668 }
3669 }
3670 }
3671
3672 /* Set up the promise. */
3673 tree promise_m
3674 = lookup_member (coro_frame_type, promise_name,
3675 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3676
3677 tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
3678 false, tf_warning_or_error);
3679
3680 if (TYPE_NEEDS_CONSTRUCTING (promise_type))
3681 {
3682 /* Do a placement new constructor for the promise type (we never call
3683 the new operator, just the constructor on the object in place in the
3684 frame).
3685
3686 First try to find a constructor with the same parameter list as the
3687 original function (if it has params), failing that find a constructor
3688 with no parameter list. */
3689
3690 if (DECL_ARGUMENTS (orig))
3691 {
3692 r = build_special_member_call (p, complete_ctor_identifier,
3693 &promise_args, promise_type,
3694 LOOKUP_NORMAL, tf_none);
3695 release_tree_vector (promise_args);
3696 }
3697 else
3698 r = NULL_TREE;
3699
3700 if (r == NULL_TREE || r == error_mark_node)
3701 r = build_special_member_call (p, complete_ctor_identifier, NULL,
3702 promise_type, LOOKUP_NORMAL,
3703 tf_warning_or_error);
3704
3705 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3706 add_stmt (r);
3707 }
3708
3709 /* Set up a new bind context for the GRO. */
3710 tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3711 /* Make and connect the scope blocks. */
3712 tree gro_block = make_node (BLOCK);
3713 BLOCK_SUPERCONTEXT (gro_block) = top_block;
3714 BLOCK_SUBBLOCKS (top_block) = gro_block;
3715 BIND_EXPR_BLOCK (gro_context_bind) = gro_block;
3716 add_stmt (gro_context_bind);
3717
3718 tree gro_meth = lookup_promise_method (orig,
3719 coro_get_return_object_identifier,
3720 fn_start, /*musthave=*/true );
3721 tree get_ro
3722 = build_new_method_call (p, gro_meth, NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
3723 tf_warning_or_error);
3724 /* Without a return object we haven't got much clue what's going on. */
3725 if (get_ro == error_mark_node)
3726 {
3727 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
3728 DECL_SAVED_TREE (orig) = newbody;
3729 return false;
3730 }
3731
3732 tree gro_context_body = push_stmt_list ();
3733 tree gro, gro_bind_vars;
3734 if (same_type_p (TREE_TYPE (get_ro), fn_return_type))
3735 {
3736 gro = DECL_RESULT (orig);
3737 gro_bind_vars = NULL_TREE; /* We don't need a separate var. */
3738 }
3739 else
3740 {
3741 gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"),
3742 TREE_TYPE (TREE_OPERAND (get_ro, 0)));
3743 DECL_CONTEXT (gro) = current_scope ();
3744 r = build_stmt (fn_start, DECL_EXPR, gro);
3745 add_stmt (r);
3746 gro_bind_vars = gro; /* We need a temporary var. */
3747 }
3748
3749 /* Initialize our actual var. */
3750 r = build2_loc (fn_start, INIT_EXPR, TREE_TYPE (gro), gro, get_ro);
3751 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3752 add_stmt (r);
3753
3754 /* Initialize the resume_idx_name to 0, meaning "not started". */
3755 tree resume_idx_m
3756 = lookup_member (coro_frame_type, resume_idx_name,
3757 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3758 tree resume_idx
3759 = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false,
3760 tf_warning_or_error);
3761 r = build_int_cst (short_unsigned_type_node, 0);
3762 r = build2_loc (fn_start, INIT_EXPR, short_unsigned_type_node, resume_idx, r);
3763 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3764 add_stmt (r);
3765
3766 /* Initialize 'initial-await-resume-called' as per
3767 [dcl.fct.def.coroutine] / 5.3 */
3768 tree i_a_r_c_m
3769 = lookup_member (coro_frame_type, iarc_name, 1, 0, tf_warning_or_error);
3770 tree i_a_r_c = build_class_member_access_expr (deref_fp, i_a_r_c_m,
3771 NULL_TREE, false,
3772 tf_warning_or_error);
3773 r = build2 (INIT_EXPR, boolean_type_node, i_a_r_c, boolean_false_node);
3774 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3775 add_stmt (r);
3776
3777 /* So .. call the actor .. */
3778 r = build_call_expr_loc (fn_start, actor, 1, coro_fp);
3779 r = maybe_cleanup_point_expr_void (r);
3780 add_stmt (r);
3781
3782 /* Switch to using 'input_location' as the loc, since we're now more
3783 logically doing things related to the end of the function. */
3784
3785 /* The ramp is done, we just need the return value. */
3786 if (!same_type_p (TREE_TYPE (gro), fn_return_type))
3787 {
3788 /* construct the return value with a single GRO param. */
3789 vec<tree, va_gc> *args = make_tree_vector_single (gro);
3790 r = build_special_member_call (DECL_RESULT (orig),
3791 complete_ctor_identifier, &args,
3792 fn_return_type, LOOKUP_NORMAL,
3793 tf_warning_or_error);
3794 r = coro_build_cvt_void_expr_stmt (r, input_location);
3795 add_stmt (r);
3796 release_tree_vector (args);
3797 }
3798 /* Else the GRO is the return and we already built it in place. */
3799
3800 bool no_warning;
3801 r = check_return_expr (DECL_RESULT (orig), &no_warning);
3802 if (error_operand_p (r) && warn_return_type)
3803 /* Suppress -Wreturn-type for the ramp. */
3804 TREE_NO_WARNING (orig) = true;
3805
3806 r = build_stmt (input_location, RETURN_EXPR, DECL_RESULT (orig));
3807 TREE_NO_WARNING (r) |= no_warning;
3808 r = maybe_cleanup_point_expr_void (r);
3809 add_stmt (r);
3810 BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
3811 BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
3812 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
3813
3814 /* We know the "real" promise and have a frame layout with a slot for each
3815 suspend point, so we can build an actor function (which contains the
3816 functionality for both 'resume' and 'destroy').
3817
3818 wrap the function body in a try {} catch (...) {} block, if exceptions
3819 are enabled. */
3820
3821 /* First make a new block for the body - that will be embedded in the
3822 re-written function. */
3823 tree first = expr_first (fnbody);
3824 bool orig_fn_has_outer_bind = false;
3825 tree replace_blk = NULL_TREE;
3826 if (first && TREE_CODE (first) == BIND_EXPR)
3827 {
3828 orig_fn_has_outer_bind = true;
3829 tree block = BIND_EXPR_BLOCK (first);
3830 replace_blk = make_node (BLOCK);
3831 if (block) /* missing block is probably an error. */
3832 {
3833 gcc_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
3834 gcc_assert (BLOCK_CHAIN (block) == NULL_TREE);
3835 BLOCK_VARS (replace_blk) = BLOCK_VARS (block);
3836 BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block);
3837 for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b))
3838 BLOCK_SUPERCONTEXT (b) = replace_blk;
3839 }
3840 BIND_EXPR_BLOCK (first) = replace_blk;
3841 }
3842
3843 /* actor's version of the promise. */
3844 tree actor_frame = build1_loc (fn_start, INDIRECT_REF, coro_frame_type,
3845 DECL_ARGUMENTS (actor));
3846 tree ap_m = lookup_member (coro_frame_type, get_identifier ("__p"), 1, 0,
3847 tf_warning_or_error);
3848 tree ap = build_class_member_access_expr (actor_frame, ap_m, NULL_TREE,
3849 false, tf_warning_or_error);
3850
3851 /* Now we've built the promise etc, process fnbody for co_returns.
3852 We want the call to return_void () below and it has no params so
3853 we can create it once here.
3854 Calls to return_value () will have to be checked and created as
3855 required. */
3856
3857 tree return_void = NULL_TREE;
3858 tree rvm
3859 = lookup_promise_method (orig, coro_return_void_identifier, fn_start,
3860 /*musthave=*/false);
3861 if (rvm && rvm != error_mark_node)
3862 return_void
3863 = build_new_method_call (ap, rvm, NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
3864 tf_warning_or_error);
3865
3866 /* [stmt.return.coroutine] (2.2 : 3) if p.return_void() is a valid
3867 expression, flowing off the end of a coroutine is equivalent to
3868 co_return; otherwise UB.
3869 We just inject the call to p.return_void() here, and fall through to
3870 the final_suspend: label (eliding the goto). If the function body has
3871 a co_return, then this statement will be unreachable and DCEd. */
3872 if (return_void != NULL_TREE)
3873 {
3874 tree append = push_stmt_list ();
3875 add_stmt (fnbody);
3876 add_stmt (return_void);
3877 fnbody = pop_stmt_list(append);
3878 }
3879
3880 if (flag_exceptions)
3881 {
3882 tree ueh_meth
3883 = lookup_promise_method (orig, coro_unhandled_exception_identifier,
3884 fn_start, /*musthave=*/true);
3885 /* Build promise.unhandled_exception(); */
3886 tree ueh
3887 = build_new_method_call (ap, ueh_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
3888 NULL, tf_warning_or_error);
3889
3890 /* The try block is just the original function, there's no real
3891 need to call any function to do this. */
3892 fnbody = build_stmt (fn_start, TRY_BLOCK, fnbody, NULL_TREE);
3893 TRY_HANDLERS (fnbody) = push_stmt_list ();
3894 /* Mimic what the parser does for the catch. */
3895 tree handler = begin_handler ();
3896 finish_handler_parms (NULL_TREE, handler); /* catch (...) */
3897
3898 /* Get the initial await resume called value. */
3899 tree i_a_r_c = build_class_member_access_expr (actor_frame, i_a_r_c_m,
3900 NULL_TREE, false,
3901 tf_warning_or_error);
3902 tree not_iarc_if = begin_if_stmt ();
3903 tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR,
3904 boolean_type_node, i_a_r_c);
3905 finish_if_stmt_cond (not_iarc, not_iarc_if);
3906 /* If the initial await resume called value is false, rethrow... */
3907 tree rethrow = build_throw (fn_start, NULL_TREE);
3908 TREE_NO_WARNING (rethrow) = true;
3909 finish_expr_stmt (rethrow);
3910 finish_then_clause (not_iarc_if);
3911 tree iarc_scope = IF_SCOPE (not_iarc_if);
3912 IF_SCOPE (not_iarc_if) = NULL;
3913 not_iarc_if = do_poplevel (iarc_scope);
3914 add_stmt (not_iarc_if);
3915 /* ... else call the promise unhandled exception method. */
3916 ueh = maybe_cleanup_point_expr_void (ueh);
3917 add_stmt (ueh);
3918 finish_handler (handler);
3919 TRY_HANDLERS (fnbody) = pop_stmt_list (TRY_HANDLERS (fnbody));
3920 /* If the function starts with a BIND_EXPR, then we need to create
3921 one here to contain the try-catch and to link up the scopes. */
3922 if (orig_fn_has_outer_bind)
3923 {
3924 fnbody = build3 (BIND_EXPR, void_type_node, NULL, fnbody, NULL);
3925 /* Make and connect the scope blocks. */
3926 tree tcb_block = make_node (BLOCK);
3927 /* .. and connect it here. */
3928 BLOCK_SUPERCONTEXT (replace_blk) = tcb_block;
3929 BLOCK_SUBBLOCKS (tcb_block) = replace_blk;
3930 BIND_EXPR_BLOCK (fnbody) = tcb_block;
3931 }
3932 }
3933 else if (pedantic)
3934 {
3935 /* We still try to look for the promise method and warn if it's not
3936 present. */
3937 tree ueh_meth
3938 = lookup_promise_method (orig, coro_unhandled_exception_identifier,
3939 fn_start, /*musthave=*/false);
3940 if (!ueh_meth || ueh_meth == error_mark_node)
3941 warning_at (fn_start, 0, "no member named %qE in %qT",
3942 coro_unhandled_exception_identifier,
3943 get_coroutine_promise_type (orig));
3944 }
3945 /* Else we don't check and don't care if the method is missing. */
3946
3947 /* Start to build the final functions.
3948
3949 We push_deferring_access_checks to avoid these routines being seen as
3950 nested by the middle end; we are doing the outlining here. */
3951
3952 push_deferring_access_checks (dk_no_check);
3953
3954 /* Actor ... */
3955 build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig, param_uses,
3956 &local_var_uses, param_dtor_list, initial_await, final_await,
3957 body_aw_points.await_number, frame_size);
3958
3959 /* Destroyer ... */
3960 build_destroy_fn (fn_start, coro_frame_type, destroy, actor);
3961
3962 pop_deferring_access_checks ();
3963
3964 DECL_SAVED_TREE (orig) = newbody;
3965 /* Link our new functions into the list. */
3966 TREE_CHAIN (destroy) = TREE_CHAIN (orig);
3967 TREE_CHAIN (actor) = destroy;
3968 TREE_CHAIN (orig) = actor;
3969
3970 *resumer = actor;
3971 *destroyer = destroy;
3972
3973 delete suspend_points;
3974 suspend_points = NULL;
3975 return true;
3976 }
3977
3978 #include "gt-cp-coroutines.h"
3979