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 : #include "rust-immutable-name-resolution-context.h"
27 :
28 : namespace Rust {
29 : namespace Analysis {
30 :
31 : class MarkLive : public MarkLiveBase
32 : {
33 : using Rust::Analysis::MarkLiveBase::visit;
34 :
35 : public:
36 : static std::set<HirId> Analysis (HIR::Crate &crate);
37 : void go (HIR::Crate &crate);
38 :
39 : void visit (HIR::PathInExpression &expr) override;
40 : void visit (HIR::FieldAccessExpr &expr) override;
41 : void visit (HIR::TupleIndexExpr &expr) override;
42 : void visit (HIR::MethodCallExpr &expr) override;
43 : void visit (HIR::TypeAlias &alias) override;
44 :
45 1647 : void visit (HIR::BorrowExpr &expr) override
46 : {
47 1647 : expr.get_expr ().accept_vis (*this);
48 1647 : }
49 :
50 395 : void visit (HIR::DereferenceExpr &expr) override
51 : {
52 395 : expr.get_expr ().accept_vis (*this);
53 395 : }
54 :
55 453 : void visit (HIR::NegationExpr &expr) override
56 : {
57 453 : expr.get_expr ().accept_vis (*this);
58 453 : }
59 :
60 903 : void visit (HIR::LazyBooleanExpr &expr) override
61 : {
62 903 : expr.get_lhs ().accept_vis (*this);
63 903 : expr.get_rhs ().accept_vis (*this);
64 903 : }
65 :
66 10142 : void visit (HIR::TypeCastExpr &expr) override
67 : {
68 10142 : expr.get_expr ().accept_vis (*this);
69 10142 : }
70 :
71 421 : void visit (HIR::GroupedExpr &expr) override
72 : {
73 421 : expr.get_expr_in_parens ().accept_vis (*this);
74 421 : }
75 :
76 360 : void visit (HIR::ArrayExpr &expr) override
77 : {
78 360 : expr.get_internal_elements ().accept_vis (*this);
79 360 : }
80 :
81 391 : void visit (HIR::ArrayIndexExpr &expr) override
82 : {
83 391 : expr.get_array_expr ().accept_vis (*this);
84 391 : expr.get_index_expr ().accept_vis (*this);
85 391 : }
86 :
87 272 : void visit (HIR::ArrayElemsValues &expr) override
88 : {
89 1675 : for (auto &elem : expr.get_values ())
90 : {
91 1403 : elem->accept_vis (*this);
92 : }
93 272 : }
94 :
95 499 : void visit (HIR::TupleExpr &expr) override
96 : {
97 1270 : for (auto &elem : expr.get_tuple_elems ())
98 : {
99 771 : elem->accept_vis (*this);
100 : }
101 499 : }
102 :
103 21724 : void visit (HIR::BlockExpr &expr) override
104 : {
105 51526 : for (auto &s : expr.get_statements ())
106 : {
107 29802 : s->accept_vis (*this);
108 : }
109 21724 : if (expr.has_expr ())
110 : {
111 12341 : expr.get_final_expr ().accept_vis (*this);
112 : }
113 21724 : }
114 :
115 5082 : void visit (HIR::UnsafeBlockExpr &expr) override
116 : {
117 5082 : expr.get_block_expr ().accept_vis (*this);
118 5082 : }
119 :
120 131 : void visit (HIR::LoopExpr &expr) override
121 : {
122 131 : expr.get_loop_block ().accept_vis (*this);
123 131 : }
124 :
125 87 : void visit (HIR::BreakExpr &expr) override
126 : {
127 87 : if (expr.has_break_expr ())
128 15 : expr.get_expr ().accept_vis (*this);
129 87 : }
130 :
131 130 : void visit (HIR::WhileLoopExpr &expr) override
132 : {
133 130 : expr.get_loop_block ().accept_vis (*this);
134 130 : expr.get_predicate_expr ().accept_vis (*this);
135 130 : }
136 :
137 11482 : void visit (HIR::Function &function) override
138 : {
139 11482 : function.get_definition ().accept_vis (*this);
140 11482 : }
141 :
142 1040 : void visit (HIR::ReturnExpr &expr) override
143 : {
144 1040 : if (expr.has_return_expr ())
145 1020 : expr.get_expr ().accept_vis (*this);
146 1040 : }
147 :
148 0 : void visit (HIR::WhileLetLoopExpr &expr) override
149 : {
150 0 : expr.get_loop_block ().accept_vis (*this);
151 0 : expr.get_cond ().accept_vis (*this);
152 0 : }
153 :
154 14000 : void visit (HIR::ExprStmt &stmt) override
155 : {
156 14000 : stmt.get_expr ().accept_vis (*this);
157 14000 : }
158 :
159 13946 : void visit (HIR::CallExpr &expr) override
160 : {
161 13946 : expr.get_fnexpr ().accept_vis (*this);
162 28966 : for (auto &argument : expr.get_arguments ())
163 15020 : argument->accept_vis (*this);
164 13946 : }
165 :
166 2926 : void visit (HIR::ArithmeticOrLogicalExpr &expr) override
167 : {
168 2926 : expr.visit_lhs (*this);
169 2926 : expr.visit_rhs (*this);
170 2926 : }
171 3017 : void visit (HIR::ComparisonExpr &expr) override
172 : {
173 3017 : expr.get_lhs ().accept_vis (*this);
174 3017 : expr.get_rhs ().accept_vis (*this);
175 3017 : }
176 :
177 2371 : void visit (HIR::AssignmentExpr &expr) override
178 : {
179 2371 : expr.visit_lhs (*this);
180 2371 : expr.visit_rhs (*this);
181 2371 : }
182 :
183 529 : void visit (HIR::CompoundAssignmentExpr &expr) override
184 : {
185 529 : expr.visit_lhs (*this);
186 529 : expr.visit_rhs (*this);
187 529 : }
188 :
189 1365 : void visit (HIR::IfExpr &expr) override
190 : {
191 1365 : expr.get_if_condition ().accept_vis (*this);
192 1365 : expr.get_if_block ().accept_vis (*this);
193 1365 : }
194 :
195 769 : void visit (HIR::IfExprConseqElse &expr) override
196 : {
197 769 : expr.get_if_condition ().accept_vis (*this);
198 769 : expr.get_if_block ().accept_vis (*this);
199 769 : expr.get_else_block ().accept_vis (*this);
200 769 : }
201 :
202 1296 : void visit (HIR::MatchExpr &expr) override
203 : {
204 1296 : expr.get_scrutinee_expr ().accept_vis (*this);
205 1296 : std::vector<HIR::MatchCase> &cases = expr.get_match_cases ();
206 4647 : for (auto &&caz : cases)
207 : {
208 3351 : auto case_arm = caz.get_arm ();
209 3351 : if (case_arm.has_match_arm_guard ())
210 0 : case_arm.get_guard_expr ().accept_vis (*this);
211 3351 : caz.get_expr ().accept_vis (*this);
212 3351 : }
213 1296 : }
214 :
215 0 : void visit (HIR::TraitItemFunc &item) override
216 : {
217 0 : item.get_block_expr ().accept_vis (*this);
218 0 : }
219 :
220 187 : void visit (HIR::ImplBlock &impl) override
221 : {
222 374 : for (auto &&item : impl.get_impl_items ())
223 : {
224 187 : item->accept_vis (*this);
225 : }
226 187 : }
227 :
228 15390 : void visit (HIR::LetStmt &stmt) override
229 : {
230 15390 : if (stmt.has_init_expr ())
231 : {
232 14291 : stmt.get_init_expr ().accept_vis (*this);
233 : }
234 15390 : }
235 :
236 77 : void visit (HIR::StructExprStruct &stct) override
237 : {
238 77 : stct.get_struct_name ().accept_vis (*this);
239 77 : }
240 :
241 1259 : void visit (HIR::StructExprStructFields &stct) override
242 : {
243 3995 : for (auto &field : stct.get_fields ())
244 : {
245 2736 : field->accept_vis (*this);
246 : }
247 :
248 1259 : stct.get_struct_name ().accept_vis (*this);
249 1259 : if (stct.has_struct_base ())
250 : {
251 63 : stct.get_struct_base ().get_base ().accept_vis (*this);
252 : }
253 1259 : }
254 :
255 2582 : virtual void visit (HIR::StructExprFieldIdentifierValue &field) override
256 : {
257 2582 : field.get_value ().accept_vis (*this);
258 2582 : }
259 :
260 0 : void visit (HIR::StructExprStructBase &stct) override
261 : {
262 0 : stct.get_struct_base ().get_base ().accept_vis (*this);
263 0 : }
264 :
265 841 : void visit (HIR::Module &module) override
266 : {
267 2978 : for (auto &item : module.get_items ())
268 2137 : item->accept_vis (*this);
269 841 : }
270 :
271 66 : void visit (HIR::ClosureExpr &expr) override
272 : {
273 66 : expr.get_expr ().accept_vis (*this);
274 66 : }
275 :
276 : private:
277 : std::vector<HirId> worklist;
278 : std::set<HirId> liveSymbols;
279 : std::set<HirId> scannedSymbols;
280 : Analysis::Mappings &mappings;
281 : const Resolver2_0::NameResolutionContext &resolver;
282 : Resolver::TypeCheckContext *tyctx;
283 4184 : MarkLive (std::vector<HirId> worklist)
284 4184 : : worklist (worklist), mappings (Analysis::Mappings::get ()),
285 4184 : resolver (
286 4184 : Resolver2_0::ImmutableNameResolutionContext::get ().resolver ()),
287 8368 : tyctx (Resolver::TypeCheckContext::get ()){};
288 :
289 : void mark_hir_id (HirId);
290 : bool visit_path_segment (HIR::PathExprSegment);
291 : void find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id);
292 : };
293 :
294 : } // namespace Analysis
295 : } // namespace Rust
296 :
297 : #endif
|