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 1610 : susp_frame_data (tree _final_susp, hash_map<tree, suspend_point_info> *_spt)
56 1610 : : fs_label (_final_susp), suspend_points (_spt)
57 : {
58 1610 : block_stack = make_tree_vector ();
59 1610 : bind_stack = make_tree_vector ();
60 1610 : }
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 1610 : local_vars_frame_data (tree *_fl, hash_map<tree, local_var_info> *_lvu)
87 1610 : : 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 6608 : bool cp_valid_coroutine () const { return valid_coroutine; }
96 : void apply_transforms ();
97 : void finish_transforms ();
98 1589 : tree get_resumer () { return resumer; }
99 1589 : tree get_destroyer () { return destroyer; }
100 :
101 : private:
102 : tree orig_fn_decl; /* The original function decl. */
103 : location_t fn_start = UNKNOWN_LOCATION;
104 : location_t fn_end = UNKNOWN_LOCATION;
105 : tree resumer = error_mark_node;
106 : tree destroyer = error_mark_node;
107 : tree coroutine_body = NULL_TREE;
108 : tree body_blocks = NULL_TREE;
109 :
110 : /* Types for this coroutine. */
111 : tree frame_type;
112 : tree frame_ptr_type;
113 : tree act_des_fn_type;
114 : tree act_des_fn_ptr_type;
115 :
116 : /* Cached information about the transformed function. */
117 : tree resume_idx_var = NULL_TREE;
118 : tree fs_label = NULL_TREE;
119 : hash_map<tree, param_info> param_uses;
120 : hash_map<tree, suspend_point_info> suspend_points;
121 : hash_map<tree, local_var_info> local_var_uses;
122 : vec<tree> param_dtor_list = vNULL;
123 : tree frame_size = NULL_TREE;
124 : unsigned int await_count = 0;
125 :
126 : bool inline_p = false;
127 : bool valid_coroutine = false;
128 :
129 : tree initial_await = error_mark_node;
130 : tree final_await = error_mark_node;
131 :
132 : void analyze_fn_parms ();
133 : void wrap_original_function_body ();
134 : bool build_ramp_function ();
135 : };
|