Branch data Line data Source code
1 : : // Copyright (C) 2021-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #ifndef RUST_HIR_LIVENESS
20 : : #define RUST_HIR_LIVENESS
21 : :
22 : : #include "rust-hir-full-decls.h"
23 : : #include "rust-hir-map.h"
24 : : #include "rust-lint-marklive-base.h"
25 : : #include "rust-name-resolver.h"
26 : :
27 : : namespace Rust {
28 : : namespace Analysis {
29 : :
30 : : class MarkLive : public MarkLiveBase
31 : : {
32 : : using Rust::Analysis::MarkLiveBase::visit;
33 : :
34 : : public:
35 : : static std::set<HirId> Analysis (HIR::Crate &crate);
36 : : void go (HIR::Crate &crate);
37 : :
38 : : void visit (HIR::PathInExpression &expr) override;
39 : : void visit (HIR::FieldAccessExpr &expr) override;
40 : : void visit (HIR::TupleIndexExpr &expr) override;
41 : : void visit (HIR::MethodCallExpr &expr) override;
42 : : void visit (HIR::TypeAlias &alias) override;
43 : :
44 : 887 : void visit (HIR::BorrowExpr &expr) override
45 : : {
46 : 887 : expr.get_expr ()->accept_vis (*this);
47 : 887 : }
48 : :
49 : 209 : void visit (HIR::DereferenceExpr &expr) override
50 : : {
51 : 209 : expr.get_expr ()->accept_vis (*this);
52 : 209 : }
53 : :
54 : 268 : void visit (HIR::NegationExpr &expr) override
55 : : {
56 : 268 : expr.get_expr ()->accept_vis (*this);
57 : 268 : }
58 : :
59 : 938 : void visit (HIR::LazyBooleanExpr &expr) override
60 : : {
61 : 938 : expr.get_lhs ()->accept_vis (*this);
62 : 938 : expr.get_rhs ()->accept_vis (*this);
63 : 938 : }
64 : :
65 : 6009 : void visit (HIR::TypeCastExpr &expr) override
66 : : {
67 : 6009 : expr.get_expr ()->accept_vis (*this);
68 : 6009 : }
69 : :
70 : 159 : void visit (HIR::GroupedExpr &expr) override
71 : : {
72 : 159 : expr.get_expr_in_parens ()->accept_vis (*this);
73 : 159 : }
74 : :
75 : 259 : void visit (HIR::ArrayExpr &expr) override
76 : : {
77 : 259 : expr.get_internal_elements ()->accept_vis (*this);
78 : 259 : }
79 : :
80 : 421 : void visit (HIR::ArrayIndexExpr &expr) override
81 : : {
82 : 421 : expr.get_array_expr ()->accept_vis (*this);
83 : 421 : expr.get_index_expr ()->accept_vis (*this);
84 : 421 : }
85 : :
86 : 175 : void visit (HIR::ArrayElemsValues &expr) override
87 : : {
88 : 1005 : for (auto &elem : expr.get_values ())
89 : : {
90 : 830 : elem->accept_vis (*this);
91 : : }
92 : 175 : }
93 : :
94 : 320 : void visit (HIR::TupleExpr &expr) override
95 : : {
96 : 965 : for (auto &elem : expr.get_tuple_elems ())
97 : : {
98 : 645 : elem->accept_vis (*this);
99 : : }
100 : 320 : }
101 : :
102 : 14175 : void visit (HIR::BlockExpr &expr) override
103 : : {
104 : 36799 : for (auto &s : expr.get_statements ())
105 : : {
106 : 22624 : s->accept_vis (*this);
107 : : }
108 : 14175 : if (expr.has_expr ())
109 : : {
110 : 7986 : expr.get_final_expr ()->accept_vis (*this);
111 : : }
112 : 14175 : }
113 : :
114 : 3117 : void visit (HIR::UnsafeBlockExpr &expr) override
115 : : {
116 : 3117 : expr.get_block_expr ()->accept_vis (*this);
117 : 3117 : }
118 : :
119 : 95 : void visit (HIR::LoopExpr &expr) override
120 : : {
121 : 95 : expr.get_loop_block ()->accept_vis (*this);
122 : 95 : }
123 : :
124 : 61 : void visit (HIR::BreakExpr &expr) override
125 : : {
126 : 61 : if (expr.has_break_expr ())
127 : 15 : expr.get_expr ()->accept_vis (*this);
128 : 61 : }
129 : :
130 : 66 : void visit (HIR::WhileLoopExpr &expr) override
131 : : {
132 : 66 : expr.get_loop_block ()->accept_vis (*this);
133 : 66 : expr.get_predicate_expr ()->accept_vis (*this);
134 : 66 : }
135 : :
136 : 8319 : void visit (HIR::Function &function) override
137 : : {
138 : 8319 : function.get_definition ()->accept_vis (*this);
139 : 8319 : }
140 : :
141 : 713 : void visit (HIR::ReturnExpr &expr) override
142 : : {
143 : 713 : if (expr.has_return_expr ())
144 : 702 : expr.get_expr ()->accept_vis (*this);
145 : 713 : }
146 : :
147 : 0 : void visit (HIR::WhileLetLoopExpr &expr) override
148 : : {
149 : 0 : expr.get_loop_block ()->accept_vis (*this);
150 : 0 : expr.get_cond ()->accept_vis (*this);
151 : 0 : }
152 : :
153 : 8780 : void visit (HIR::ExprStmt &stmt) override
154 : : {
155 : 8780 : stmt.get_expr ()->accept_vis (*this);
156 : 8780 : }
157 : :
158 : 8705 : void visit (HIR::CallExpr &expr) override
159 : : {
160 : 8705 : expr.get_fnexpr ()->accept_vis (*this);
161 : 18850 : for (auto &argument : expr.get_arguments ())
162 : 10145 : argument->accept_vis (*this);
163 : 8705 : }
164 : :
165 : 2254 : void visit (HIR::ArithmeticOrLogicalExpr &expr) override
166 : : {
167 : 2254 : expr.visit_lhs (*this);
168 : 2254 : expr.visit_rhs (*this);
169 : 2254 : }
170 : 1699 : void visit (HIR::ComparisonExpr &expr) override
171 : : {
172 : 1699 : expr.get_lhs ()->accept_vis (*this);
173 : 1699 : expr.get_rhs ()->accept_vis (*this);
174 : 1699 : }
175 : :
176 : 2178 : void visit (HIR::AssignmentExpr &expr) override
177 : : {
178 : 2178 : expr.visit_lhs (*this);
179 : 2178 : expr.visit_rhs (*this);
180 : 2178 : }
181 : :
182 : 171 : void visit (HIR::CompoundAssignmentExpr &expr) override
183 : : {
184 : 171 : expr.visit_lhs (*this);
185 : 171 : expr.visit_rhs (*this);
186 : 171 : }
187 : :
188 : 325 : void visit (HIR::IfExpr &expr) override
189 : : {
190 : 325 : expr.get_if_condition ()->accept_vis (*this);
191 : 325 : expr.get_if_block ()->accept_vis (*this);
192 : 325 : }
193 : :
194 : 410 : void visit (HIR::IfExprConseqElse &expr) override
195 : : {
196 : 410 : expr.get_if_condition ()->accept_vis (*this);
197 : 410 : expr.get_if_block ()->accept_vis (*this);
198 : 410 : expr.get_else_block ()->accept_vis (*this);
199 : 410 : }
200 : :
201 : 635 : void visit (HIR::MatchExpr &expr) override
202 : : {
203 : 635 : expr.get_scrutinee_expr ()->accept_vis (*this);
204 : 635 : std::vector<HIR::MatchCase> &cases = expr.get_match_cases ();
205 : 2410 : for (auto &&caz : cases)
206 : : {
207 : 1775 : auto case_arm = caz.get_arm ();
208 : 1775 : if (case_arm.has_match_arm_guard ())
209 : 0 : case_arm.get_guard_expr ()->accept_vis (*this);
210 : 1775 : caz.get_expr ()->accept_vis (*this);
211 : 1775 : }
212 : 635 : }
213 : :
214 : 0 : void visit (HIR::TraitItemFunc &item) override
215 : : {
216 : 0 : item.get_block_expr ()->accept_vis (*this);
217 : 0 : }
218 : :
219 : 139 : void visit (HIR::ImplBlock &impl) override
220 : : {
221 : 278 : for (auto &&item : impl.get_impl_items ())
222 : : {
223 : 139 : item->accept_vis (*this);
224 : : }
225 : 139 : }
226 : :
227 : 13494 : void visit (HIR::LetStmt &stmt) override
228 : : {
229 : 13494 : if (stmt.has_init_expr ())
230 : : {
231 : 12427 : stmt.get_init_expr ()->accept_vis (*this);
232 : : }
233 : 13494 : }
234 : :
235 : 50 : void visit (HIR::StructExprStruct &stct) override
236 : : {
237 : 50 : stct.get_struct_name ().accept_vis (*this);
238 : 50 : }
239 : :
240 : 763 : void visit (HIR::StructExprStructFields &stct) override
241 : : {
242 : 2778 : for (auto &field : stct.get_fields ())
243 : : {
244 : 2015 : field->accept_vis (*this);
245 : : }
246 : :
247 : 763 : stct.get_struct_name ().accept_vis (*this);
248 : 763 : if (stct.has_struct_base ())
249 : : {
250 : 63 : stct.struct_base->base_struct->accept_vis (*this);
251 : : }
252 : 763 : }
253 : :
254 : 1861 : virtual void visit (HIR::StructExprFieldIdentifierValue &field) override
255 : : {
256 : 1861 : field.get_value ()->accept_vis (*this);
257 : 1861 : }
258 : :
259 : 0 : void visit (HIR::StructExprStructBase &stct) override
260 : : {
261 : 0 : stct.get_struct_base ()->base_struct->accept_vis (*this);
262 : 0 : }
263 : :
264 : 368 : void visit (HIR::Module &module) override
265 : : {
266 : 1134 : for (auto &item : module.get_items ())
267 : 766 : item->accept_vis (*this);
268 : 368 : }
269 : :
270 : 58 : void visit (HIR::ClosureExpr &expr) override
271 : : {
272 : 58 : expr.get_expr ()->accept_vis (*this);
273 : 58 : }
274 : :
275 : : private:
276 : : std::vector<HirId> worklist;
277 : : std::set<HirId> liveSymbols;
278 : : std::set<HirId> scannedSymbols;
279 : : Analysis::Mappings *mappings;
280 : : Resolver::Resolver *resolver;
281 : : Resolver::TypeCheckContext *tyctx;
282 : 3290 : MarkLive (std::vector<HirId> worklist)
283 : 3290 : : worklist (worklist), mappings (Analysis::Mappings::get ()),
284 : 3290 : resolver (Resolver::Resolver::get ()),
285 : 6580 : tyctx (Resolver::TypeCheckContext::get ()){};
286 : :
287 : : void mark_hir_id (HirId);
288 : : bool visit_path_segment (HIR::PathExprSegment);
289 : : void find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id);
290 : : };
291 : :
292 : : } // namespace Analysis
293 : : } // namespace Rust
294 : :
295 : : #endif
|