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 fr_copy_dtor; /* If we need a DTOR on exception, this is it. */
13 : : bool by_ref; /* Was passed by reference. */
14 : : bool pt_ref; /* Was a pointer to object. */
15 : : bool rv_ref; /* Was an rvalue ref. */
16 : : bool trivial_dtor; /* The frame type has a trivial DTOR. */
17 : : bool this_ptr; /* Is 'this' */
18 : : bool lambda_cobj; /* Lambda capture object */
19 : : };
20 : :
21 : : /* Suspend point hash_map. */
22 : :
23 : : struct suspend_point_info
24 : : {
25 : : /* coro frame field type. */
26 : : tree awaitable_type;
27 : : /* coro frame field name. */
28 : : tree await_field_id;
29 : : };
30 : :
31 : : /* This data set is used when analyzing statements for await expressions. */
32 : :
33 : : struct susp_frame_data
34 : : {
35 : : /* Function-wide. */
36 : : tree fs_label; /* The destination for co_returns. */
37 : : hash_map<tree, suspend_point_info> *suspend_points; /* Not owned. */
38 : : vec<tree, va_gc> *block_stack; /* Track block scopes. */
39 : : vec<tree, va_gc> *bind_stack; /* Track current bind expr. */
40 : : unsigned await_number = 0; /* Which await in the function. */
41 : : unsigned cond_number = 0; /* Which replaced condition in the fn. */
42 : :
43 : : /* Temporary values for one statement or expression being analyzed. */
44 : : /* The set of TRUTH exprs to expand. */
45 : : hash_set<tree> *truth_aoif_to_expand = nullptr;
46 : : /* Count of awaits in this statement */
47 : : unsigned saw_awaits = 0;
48 : : /* This expr captures temps by ref. */
49 : : bool captures_temporary = false;
50 : : /* We must expand a truth_if expression. */
51 : : bool needs_truth_if_exp = false;
52 : : /* We must handle initializing an awaiter. */
53 : : bool has_awaiter_init = false;
54 : :
55 : 1580 : susp_frame_data (tree _final_susp, hash_map<tree, suspend_point_info> *_spt)
56 : 1580 : : fs_label (_final_susp), suspend_points (_spt)
57 : : {
58 : 1580 : block_stack = make_tree_vector ();
59 : 1580 : bind_stack = make_tree_vector ();
60 : 1580 : }
61 : : };
62 : :
63 : : struct local_var_info
64 : : {
65 : : tree field_id;
66 : : tree field_idx;
67 : : tree frame_type;
68 : : bool is_lambda_capture;
69 : : bool is_static;
70 : : bool has_value_expr_p;
71 : : location_t def_loc;
72 : : };
73 : :
74 : : /* For recording local variable usage. */
75 : :
76 : : struct local_vars_frame_data
77 : : {
78 : : tree *field_list;
79 : : hash_map<tree, local_var_info> *local_var_uses;
80 : : unsigned int nest_depth = 0;
81 : : unsigned int bind_indx = 0;
82 : : location_t loc = UNKNOWN_LOCATION;
83 : : bool saw_capture = false;
84 : : bool local_var_seen = false;
85 : :
86 : 1580 : local_vars_frame_data (tree *_fl, hash_map<tree, local_var_info> *_lvu)
87 : 1580 : : field_list (_fl), local_var_uses (_lvu) {}
88 : : };
89 : :
90 : : class cp_coroutine_transform {
91 : : public:
92 : : cp_coroutine_transform (tree, bool);
93 : : ~cp_coroutine_transform ();
94 : :
95 : 6488 : bool cp_valid_coroutine () const { return valid_coroutine; }
96 : : void apply_transforms ();
97 : : void finish_transforms ();
98 : 1559 : tree get_resumer () { return resumer; }
99 : 1559 : tree get_destroyer () { return destroyer; }
100 : :
101 : : private:
102 : : tree orig_fn_decl; /* The original function decl. */
103 : : tree orig_fn_body = NULL_TREE; /* The original function body. */
104 : : location_t fn_start = UNKNOWN_LOCATION;
105 : : location_t fn_end = 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 : : tree initial_await = error_mark_node;
131 : : tree final_await = error_mark_node;
132 : :
133 : : void analyze_fn_parms ();
134 : : void wrap_original_function_body ();
135 : : bool build_ramp_function ();
136 : : };
|