@@ -206,11 +206,10 @@ struct GTY((for_user)) coroutine_info
206
206
tree traits_type; /* The cached traits type for this function. */
207
207
tree handle_type; /* The cached coroutine handle for this function. */
208
208
tree self_h_proxy; /* A handle instance that is used as the proxy for the
209
- one that will eventually be allocated in the coroutine
210
- frame. */
209
+ one that will eventually be built in lowering. */
211
210
tree promise_proxy; /* Likewise, a proxy promise instance. */
212
- tree from_address; /* handle_type from_address function. */
213
- tree return_void; /* The expression for p.return_void() if it exists. */
211
+ tree from_address; /* handle_type from_address() function. */
212
+ tree return_void; /* The expression for p.return_void(), if it exists. */
214
213
location_t first_coro_keyword; /* The location of the keyword that made this
215
214
function into a coroutine. */
216
215
@@ -1982,12 +1981,13 @@ struct coro_aw_data
1982
1981
tree coro_fp; /* Frame pointer var. */
1983
1982
tree resume_idx; /* This is the index var in the frame. */
1984
1983
tree i_a_r_c; /* initial suspend await_resume() was called if true. */
1985
- tree self_h; /* This is a handle to the current coro (frame var). */
1986
1984
tree cleanup; /* This is where to go once we complete local destroy. */
1987
1985
tree cororet; /* This is where to go if we suspend. */
1988
1986
tree corocont; /* This is where to go if we continue. */
1989
1987
tree dispatch; /* This is where we go if we restart the dispatch. */
1990
1988
tree conthand; /* This is the handle for a continuation. */
1989
+ tree handle_type; /* Handle type for this coroutine... */
1990
+ tree hfa_m; /* ... and handle.from_address() for this. */
1991
1991
unsigned index; /* This is our current resume index. */
1992
1992
};
1993
1993
@@ -2105,6 +2105,18 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d)
2105
2105
2106
2106
tree suspend = TREE_VEC_ELT (awaiter_calls, 1 ); /* await_suspend(). */
2107
2107
tree susp_type = TREE_TYPE (suspend);
2108
+ tree susp_call = suspend;
2109
+ if (TREE_CODE (suspend) == TARGET_EXPR)
2110
+ susp_call = TARGET_EXPR_INITIAL (suspend);
2111
+ gcc_checking_assert (TREE_CODE (susp_call) == CALL_EXPR);
2112
+ tree dummy_ch = build_dummy_object (data->handle_type );
2113
+ r = fold_convert (build_pointer_type (void_type_node), data->coro_fp );
2114
+ vec<tree, va_gc> *args = make_tree_vector_single (r);
2115
+ tree hfa = cp_fold_rvalue (
2116
+ build_new_method_call (dummy_ch, data->hfa_m , &args, NULL_TREE,
2117
+ LOOKUP_NORMAL, NULL , tf_warning_or_error));
2118
+ release_tree_vector (args);
2119
+ CALL_EXPR_ARG (susp_call, call_expr_nargs (susp_call) - 1 ) = hfa;
2108
2120
2109
2121
bool is_cont = false ;
2110
2122
/* NOTE: final suspend can't resume; the "resume" label in that case
@@ -2586,22 +2598,6 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2586
2598
/* Now we start building the rewritten function body. */
2587
2599
add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label));
2588
2600
2589
- /* actor's coroutine 'self handle'. */
2590
- tree ash = coro_build_frame_access_expr (actor_frame, coro_self_handle_id,
2591
- false , tf_warning_or_error);
2592
- /* So construct the self-handle from the frame address. */
2593
- tree hfa_m = get_coroutine_from_address (orig);
2594
- /* Should have been set earlier by coro_promise_type_found_p. */
2595
- gcc_assert (hfa_m);
2596
-
2597
- tree r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
2598
- vec<tree, va_gc> *args = make_tree_vector_single (r);
2599
- tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
2600
- NULL , tf_warning_or_error);
2601
- r = cp_build_init_expr (ash, hfa);
2602
- finish_expr_stmt (r);
2603
- release_tree_vector (args);
2604
-
2605
2601
/* Now we know the real promise, and enough about the frame layout to
2606
2602
decide where to put things. */
2607
2603
@@ -2616,7 +2612,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2616
2612
add_stmt (fnbody);
2617
2613
2618
2614
/* Now do the tail of the function; first cleanups. */
2619
- r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2615
+ tree r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2620
2616
add_stmt (r);
2621
2617
2622
2618
/* Destructors for the things we built explicitly.
@@ -2684,6 +2680,12 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2684
2680
gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
2685
2681
add_stmt (r);
2686
2682
2683
+ /* How to construct the handle for this coroutine from the frame address. */
2684
+ tree hfa_m = get_coroutine_from_address (orig);
2685
+ /* Should have been set earlier by coro_promise_type_found_p. */
2686
+ gcc_assert (hfa_m);
2687
+ tree handle_type = TREE_TYPE (get_coroutine_self_handle_proxy (orig));
2688
+
2687
2689
/* We've now rewritten the tree and added the initial and final
2688
2690
co_awaits. Now pass over the tree and expand the co_awaits. */
2689
2691
tree i_a_r_c = NULL_TREE;
@@ -2692,8 +2694,9 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2692
2694
false , tf_warning_or_error);
2693
2695
2694
2696
coro_aw_data data = {actor, actor_fp, resume_idx_var, i_a_r_c,
2695
- ash, del_promise_label, ret_label,
2696
- continue_label, restart_dispatch_label, continuation, 2 };
2697
+ del_promise_label, ret_label,
2698
+ continue_label, restart_dispatch_label, continuation,
2699
+ handle_type, hfa_m, 2 };
2697
2700
cp_walk_tree (&actor_body, await_statement_expander, &data, NULL );
2698
2701
2699
2702
BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
@@ -4424,16 +4427,6 @@ cp_coroutine_transform::wrap_original_function_body ()
4424
4427
var_list = promise;
4425
4428
add_decl_expr (promise);
4426
4429
4427
- /* We need a handle to this coroutine, which is passed to every
4428
- await_suspend(). This was created on demand when parsing we now link it
4429
- into our scope. */
4430
- var = get_coroutine_self_handle_proxy (orig_fn_decl);
4431
- DECL_CONTEXT (var) = orig_fn_decl;
4432
- DECL_SOURCE_LOCATION (var) = loc;
4433
- DECL_CHAIN (var) = var_list;
4434
- var_list = var;
4435
- add_decl_expr (var);
4436
-
4437
4430
/* If we have function parms, then these will be copied to the coroutine
4438
4431
frame as per [dcl.fct.def.coroutine] / 13.
4439
4432
Here, we create a local (proxy) variable for each parm, since the original
@@ -5285,7 +5278,6 @@ cp_coroutine_transform::~cp_coroutine_transform ()
5285
5278
bool _Coro_frame_needs_free; free the coro frame mem if set.
5286
5279
bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3
5287
5280
short _Coro_resume_index;
5288
- handle_type _Coro_self_handle;
5289
5281
parameter copies (were required).
5290
5282
local variables saved (including awaitables)
5291
5283
(maybe) trailing space.
0 commit comments