Branch data Line data Source code
1 : :
2 : : /* This caches information that we determine about function params,
3 : : their uses and copies in the coroutine frame. */
4 : :
5 : : struct param_info
6 : : {
7 : : tree field_id; /* The name of the copy in the coroutine frame. */
8 : : tree copy_var; /* The local var proxy for the frame copy. */
9 : : vec<tree *> *body_uses; /* Worklist of uses, void if there are none. */
10 : : tree frame_type; /* The type used to represent this parm in the frame. */
11 : : tree orig_type; /* The original type of the parm (not as passed). */
12 : : tree guard_var; /* If we need a DTOR on exception, this bool guards it. */
13 : : tree fr_copy_dtor; /* If we need a DTOR on exception, this is it. */
14 : : bool by_ref; /* Was passed by reference. */
15 : : bool pt_ref; /* Was a pointer to object. */
16 : : bool rv_ref; /* Was an rvalue ref. */
17 : : bool trivial_dtor; /* The frame type has a trivial DTOR. */
18 : : bool this_ptr; /* Is 'this' */
19 : : bool lambda_cobj; /* Lambda capture object */
20 : : };
21 : :
22 : : /* Suspend point hash_map. */
23 : :
24 : : struct suspend_point_info
25 : : {
26 : : /* coro frame field type. */
27 : : tree awaitable_type;
28 : : /* coro frame field name. */
29 : : tree await_field_id;
30 : : };
31 : :
32 : : /* This data set is used when analyzing statements for await expressions. */
33 : :
34 : : struct susp_frame_data
35 : : {
36 : : /* Function-wide. */
37 : : tree fs_label; /* The destination for co_returns. */
38 : : hash_map<tree, suspend_point_info> *suspend_points; /* Not owned. */
39 : : vec<tree, va_gc> *block_stack; /* Track block scopes. */
40 : : vec<tree, va_gc> *bind_stack; /* Track current bind expr. */
41 : : unsigned await_number = 0; /* Which await in the function. */
42 : : unsigned cond_number = 0; /* Which replaced condition in the fn. */
43 : :
44 : : /* Temporary values for one statement or expression being analyzed. */
45 : : /* The set of TRUTH exprs to expand. */
46 : : hash_set<tree> *truth_aoif_to_expand = nullptr;
47 : : /* Count of awaits in this statement */
48 : : unsigned saw_awaits = 0;
49 : : /* This expr captures temps by ref. */
50 : : bool captures_temporary = false;
51 : : /* We must expand a truth_if expression. */
52 : : bool needs_truth_if_exp = false;
53 : : /* We must handle initializing an awaiter. */
54 : : bool has_awaiter_init = false;
55 : :
56 : 1366 : susp_frame_data (tree _final_susp, hash_map<tree, suspend_point_info> *_spt)
57 : 1366 : : fs_label (_final_susp), suspend_points (_spt)
58 : : {
59 : 1366 : block_stack = make_tree_vector ();
60 : 1366 : bind_stack = make_tree_vector ();
61 : 1366 : }
62 : : };
63 : :
64 : : struct local_var_info
65 : : {
66 : : tree field_id;
67 : : tree field_idx;
68 : : tree frame_type;
69 : : bool is_lambda_capture;
70 : : bool is_static;
71 : : bool has_value_expr_p;
72 : : location_t def_loc;
73 : : };
74 : :
75 : : /* For recording local variable usage. */
76 : :
77 : : struct local_vars_frame_data
78 : : {
79 : : tree *field_list;
80 : : hash_map<tree, local_var_info> *local_var_uses;
81 : : unsigned int nest_depth = 0;
82 : : unsigned int bind_indx = 0;
83 : : location_t loc = UNKNOWN_LOCATION;
84 : : bool saw_capture = false;
85 : : bool local_var_seen = false;
86 : :
87 : 1366 : local_vars_frame_data (tree *_fl, hash_map<tree, local_var_info> *_lvu)
88 : 1366 : : field_list (_fl), local_var_uses (_lvu) {}
89 : : };
90 : :
91 : : class cp_coroutine_transform {
92 : : public:
93 : : cp_coroutine_transform (tree, bool);
94 : : ~cp_coroutine_transform ();
95 : :
96 : 5517 : bool cp_valid_coroutine () const { return valid_coroutine; }
97 : : void apply_transforms ();
98 : : void finish_transforms ();
99 : 1356 : tree get_resumer () { return resumer; }
100 : 1356 : tree get_destroyer () { return destroyer; }
101 : :
102 : : private:
103 : : tree orig_fn_decl; /* The original function decl. */
104 : : tree orig_fn_body = NULL_TREE; /* The original function body. */
105 : : location_t fn_start = UNKNOWN_LOCATION;
106 : : tree resumer = error_mark_node;
107 : : tree destroyer = error_mark_node;
108 : : tree coroutine_body = NULL_TREE;
109 : : tree body_blocks = NULL_TREE;
110 : :
111 : : /* Types for this coroutine. */
112 : : tree frame_type;
113 : : tree frame_ptr_type;
114 : : tree act_des_fn_type;
115 : : tree act_des_fn_ptr_type;
116 : :
117 : : /* Cached information about the transformed function. */
118 : : tree resume_idx_var = NULL_TREE;
119 : : tree fs_label = NULL_TREE;
120 : : hash_map<tree, param_info> param_uses;
121 : : hash_map<tree, suspend_point_info> suspend_points;
122 : : hash_map<tree, local_var_info> local_var_uses;
123 : : vec<tree> param_dtor_list = vNULL;
124 : : tree frame_size = NULL_TREE;
125 : : unsigned int await_count = 0;
126 : :
127 : : bool inline_p = false;
128 : : bool valid_coroutine = false;
129 : :
130 : : void wrap_original_function_body ();
131 : : bool build_ramp_function ();
132 : : };
|