Line data Source code
1 : // Copyright (C) 2021-2026 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 1647 : void visit (HIR::BorrowExpr &expr) override
45 : {
46 1647 : expr.get_expr ().accept_vis (*this);
47 1647 : }
48 :
49 395 : void visit (HIR::DereferenceExpr &expr) override
50 : {
51 395 : expr.get_expr ().accept_vis (*this);
52 395 : }
53 :
54 299 : void visit (HIR::NegationExpr &expr) override
55 : {
56 299 : expr.get_expr ().accept_vis (*this);
57 299 : }
58 :
59 903 : void visit (HIR::LazyBooleanExpr &expr) override
60 : {
61 903 : expr.get_lhs ().accept_vis (*this);
62 903 : expr.get_rhs ().accept_vis (*this);
63 903 : }
64 :
65 10139 : void visit (HIR::TypeCastExpr &expr) override
66 : {
67 10139 : expr.get_expr ().accept_vis (*this);
68 10139 : }
69 :
70 418 : void visit (HIR::GroupedExpr &expr) override
71 : {
72 418 : expr.get_expr_in_parens ().accept_vis (*this);
73 418 : }
74 :
75 352 : void visit (HIR::ArrayExpr &expr) override
76 : {
77 352 : expr.get_internal_elements ().accept_vis (*this);
78 352 : }
79 :
80 295 : void visit (HIR::ArrayIndexExpr &expr) override
81 : {
82 295 : expr.get_array_expr ().accept_vis (*this);
83 295 : expr.get_index_expr ().accept_vis (*this);
84 295 : }
85 :
86 264 : void visit (HIR::ArrayElemsValues &expr) override
87 : {
88 1571 : for (auto &elem : expr.get_values ())
89 : {
90 1307 : elem->accept_vis (*this);
91 : }
92 264 : }
93 :
94 498 : void visit (HIR::TupleExpr &expr) override
95 : {
96 1266 : for (auto &elem : expr.get_tuple_elems ())
97 : {
98 768 : elem->accept_vis (*this);
99 : }
100 498 : }
101 :
102 20678 : void visit (HIR::BlockExpr &expr) override
103 : {
104 48833 : for (auto &s : expr.get_statements ())
105 : {
106 28155 : s->accept_vis (*this);
107 : }
108 20678 : if (expr.has_expr ())
109 : {
110 12108 : expr.get_final_expr ().accept_vis (*this);
111 : }
112 20678 : }
113 :
114 5004 : void visit (HIR::UnsafeBlockExpr &expr) override
115 : {
116 5004 : expr.get_block_expr ().accept_vis (*this);
117 5004 : }
118 :
119 131 : void visit (HIR::LoopExpr &expr) override
120 : {
121 131 : expr.get_loop_block ().accept_vis (*this);
122 131 : }
123 :
124 87 : void visit (HIR::BreakExpr &expr) override
125 : {
126 87 : if (expr.has_break_expr ())
127 15 : expr.get_expr ().accept_vis (*this);
128 87 : }
129 :
130 130 : void visit (HIR::WhileLoopExpr &expr) override
131 : {
132 130 : expr.get_loop_block ().accept_vis (*this);
133 130 : expr.get_predicate_expr ().accept_vis (*this);
134 130 : }
135 :
136 11324 : void visit (HIR::Function &function) override
137 : {
138 11324 : function.get_definition ().accept_vis (*this);
139 11324 : }
140 :
141 1037 : void visit (HIR::ReturnExpr &expr) override
142 : {
143 1037 : if (expr.has_return_expr ())
144 1017 : expr.get_expr ().accept_vis (*this);
145 1037 : }
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 12383 : void visit (HIR::ExprStmt &stmt) override
154 : {
155 12383 : stmt.get_expr ().accept_vis (*this);
156 12383 : }
157 :
158 12420 : void visit (HIR::CallExpr &expr) override
159 : {
160 12420 : expr.get_fnexpr ().accept_vis (*this);
161 26723 : for (auto &argument : expr.get_arguments ())
162 14303 : argument->accept_vis (*this);
163 12420 : }
164 :
165 2922 : void visit (HIR::ArithmeticOrLogicalExpr &expr) override
166 : {
167 2922 : expr.visit_lhs (*this);
168 2922 : expr.visit_rhs (*this);
169 2922 : }
170 2210 : void visit (HIR::ComparisonExpr &expr) override
171 : {
172 2210 : expr.get_lhs ().accept_vis (*this);
173 2210 : expr.get_rhs ().accept_vis (*this);
174 2210 : }
175 :
176 2364 : void visit (HIR::AssignmentExpr &expr) override
177 : {
178 2364 : expr.visit_lhs (*this);
179 2364 : expr.visit_rhs (*this);
180 2364 : }
181 :
182 529 : void visit (HIR::CompoundAssignmentExpr &expr) override
183 : {
184 529 : expr.visit_lhs (*this);
185 529 : expr.visit_rhs (*this);
186 529 : }
187 :
188 558 : void visit (HIR::IfExpr &expr) override
189 : {
190 558 : expr.get_if_condition ().accept_vis (*this);
191 558 : expr.get_if_block ().accept_vis (*this);
192 558 : }
193 :
194 769 : void visit (HIR::IfExprConseqElse &expr) override
195 : {
196 769 : expr.get_if_condition ().accept_vis (*this);
197 769 : expr.get_if_block ().accept_vis (*this);
198 769 : expr.get_else_block ().accept_vis (*this);
199 769 : }
200 :
201 1291 : void visit (HIR::MatchExpr &expr) override
202 : {
203 1291 : expr.get_scrutinee_expr ().accept_vis (*this);
204 1291 : std::vector<HIR::MatchCase> &cases = expr.get_match_cases ();
205 4631 : for (auto &&caz : cases)
206 : {
207 3340 : auto case_arm = caz.get_arm ();
208 3340 : if (case_arm.has_match_arm_guard ())
209 0 : case_arm.get_guard_expr ().accept_vis (*this);
210 3340 : caz.get_expr ().accept_vis (*this);
211 3340 : }
212 1291 : }
213 :
214 0 : void visit (HIR::TraitItemFunc &item) override
215 : {
216 0 : item.get_block_expr ().accept_vis (*this);
217 0 : }
218 :
219 187 : void visit (HIR::ImplBlock &impl) override
220 : {
221 374 : for (auto &&item : impl.get_impl_items ())
222 : {
223 187 : item->accept_vis (*this);
224 : }
225 187 : }
226 :
227 15362 : void visit (HIR::LetStmt &stmt) override
228 : {
229 15362 : if (stmt.has_init_expr ())
230 : {
231 14263 : stmt.get_init_expr ().accept_vis (*this);
232 : }
233 15362 : }
234 :
235 77 : void visit (HIR::StructExprStruct &stct) override
236 : {
237 77 : stct.get_struct_name ().accept_vis (*this);
238 77 : }
239 :
240 1243 : void visit (HIR::StructExprStructFields &stct) override
241 : {
242 3963 : for (auto &field : stct.get_fields ())
243 : {
244 2720 : field->accept_vis (*this);
245 : }
246 :
247 1243 : stct.get_struct_name ().accept_vis (*this);
248 1243 : if (stct.has_struct_base ())
249 : {
250 63 : stct.get_struct_base ().get_base ().accept_vis (*this);
251 : }
252 1243 : }
253 :
254 2566 : virtual void visit (HIR::StructExprFieldIdentifierValue &field) override
255 : {
256 2566 : field.get_value ().accept_vis (*this);
257 2566 : }
258 :
259 0 : void visit (HIR::StructExprStructBase &stct) override
260 : {
261 0 : stct.get_struct_base ().get_base ().accept_vis (*this);
262 0 : }
263 :
264 841 : void visit (HIR::Module &module) override
265 : {
266 2978 : for (auto &item : module.get_items ())
267 2137 : item->accept_vis (*this);
268 841 : }
269 :
270 66 : void visit (HIR::ClosureExpr &expr) override
271 : {
272 66 : expr.get_expr ().accept_vis (*this);
273 66 : }
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 4028 : MarkLive (std::vector<HirId> worklist)
283 4028 : : worklist (worklist), mappings (Analysis::Mappings::get ()),
284 4028 : resolver (Resolver::Resolver::get ()),
285 8056 : 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
|