Line data Source code
1 : // Copyright (C) 2020-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_AST_LOWER_BLOCK
20 : #define RUST_AST_LOWER_BLOCK
21 :
22 : #include "rust-diagnostics.h"
23 : #include "rust-ast-lower-base.h"
24 :
25 : namespace Rust {
26 : namespace HIR {
27 :
28 47136 : class ASTLoweringBlock : public ASTLoweringBase
29 : {
30 : using Rust::HIR::ASTLoweringBase::visit;
31 :
32 : public:
33 42107 : static HIR::BlockExpr *translate (AST::BlockExpr &expr, bool *terminated)
34 : {
35 84214 : ASTLoweringBlock resolver;
36 42107 : expr.normalize_tail_expr ();
37 42107 : expr.accept_vis (resolver);
38 42107 : if (resolver.translated != nullptr)
39 : {
40 42107 : resolver.mappings.hir.exprs.insert (resolver.translated);
41 : }
42 :
43 42107 : *terminated = resolver.terminated;
44 42107 : return resolver.translated;
45 42107 : }
46 :
47 5029 : static HIR::UnsafeBlockExpr *translate (AST::UnsafeBlockExpr &expr,
48 : bool *terminated)
49 : {
50 10058 : ASTLoweringBlock resolver;
51 :
52 5029 : HIR::BlockExpr *block
53 5029 : = ASTLoweringBlock::translate (expr.get_block_expr (), terminated);
54 5029 : auto crate_num = resolver.mappings.crate.get_current_crate ();
55 10058 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
56 : resolver.mappings.get_next_hir_id (
57 : crate_num),
58 5029 : UNKNOWN_LOCAL_DEFID);
59 :
60 5029 : HIR::UnsafeBlockExpr *translated
61 : = new HIR::UnsafeBlockExpr (mapping,
62 5029 : std::unique_ptr<HIR::BlockExpr> (block),
63 5029 : expr.get_outer_attrs (), expr.get_locus ());
64 :
65 5029 : resolver.mappings.hir.exprs.insert (translated);
66 :
67 5029 : return translated;
68 5029 : }
69 :
70 : void visit (AST::BlockExpr &expr) override;
71 :
72 : private:
73 47136 : ASTLoweringBlock ()
74 47136 : : ASTLoweringBase (), translated (nullptr), terminated (false)
75 : {}
76 :
77 : HIR::BlockExpr *translated;
78 : bool terminated;
79 : };
80 :
81 : class ASTLoweringIfBlock : public ASTLoweringBase
82 : {
83 : using Rust::HIR::ASTLoweringBase::visit;
84 :
85 : public:
86 4356 : static HIR::IfExpr *translate (AST::IfExpr &expr, bool *terminated)
87 : {
88 8712 : ASTLoweringIfBlock resolver;
89 4356 : expr.accept_vis (resolver);
90 4356 : if (resolver.translated != nullptr)
91 : {
92 4356 : resolver.mappings.hir.exprs.insert (resolver.translated);
93 : }
94 4356 : *terminated = resolver.terminated;
95 4356 : return resolver.translated;
96 4356 : }
97 :
98 4356 : ~ASTLoweringIfBlock () {}
99 :
100 : void visit (AST::IfExpr &expr) override;
101 :
102 : void visit (AST::IfExprConseqElse &expr) override;
103 :
104 : private:
105 4356 : ASTLoweringIfBlock ()
106 4356 : : ASTLoweringBase (), translated (nullptr), terminated (false)
107 : {}
108 :
109 : HIR::IfExpr *translated;
110 : bool terminated;
111 : };
112 :
113 : class ASTLoweringIfLetBlock : public ASTLoweringBase
114 : {
115 : using Rust::HIR::ASTLoweringBase::visit;
116 :
117 : public:
118 120 : static HIR::MatchExpr *translate (AST::IfLetExpr &expr)
119 : {
120 240 : ASTLoweringIfLetBlock resolver;
121 120 : expr.accept_vis (resolver);
122 120 : if (resolver.translated != nullptr)
123 : {
124 120 : resolver.mappings.hir.exprs.insert (resolver.translated);
125 : }
126 120 : return resolver.translated;
127 120 : }
128 :
129 120 : ~ASTLoweringIfLetBlock () {}
130 :
131 : void visit (AST::IfLetExpr &expr) override;
132 :
133 : void visit (AST::IfLetExprConseqElse &expr) override;
134 :
135 : private:
136 120 : ASTLoweringIfLetBlock () : ASTLoweringBase (), translated (nullptr) {}
137 :
138 : void desugar_iflet (AST::IfLetExpr &, HIR::Expr **, HIR::Expr *,
139 : std::vector<HIR::MatchCase> &);
140 :
141 : HIR::MatchExpr *translated;
142 : };
143 :
144 : class ASTLoweringExprWithBlock : public ASTLoweringBase
145 : {
146 : using Rust::HIR::ASTLoweringBase::visit;
147 :
148 : public:
149 9174 : static HIR::ExprWithBlock *translate (AST::ExprWithBlock &expr,
150 : bool *terminated)
151 : {
152 18348 : ASTLoweringExprWithBlock resolver;
153 9174 : expr.accept_vis (resolver);
154 9174 : if (resolver.translated != nullptr)
155 9174 : resolver.mappings.hir.exprs.insert (resolver.translated);
156 :
157 9174 : *terminated = resolver.terminated;
158 9174 : return resolver.translated;
159 9174 : }
160 :
161 9174 : ~ASTLoweringExprWithBlock () {}
162 :
163 16 : void visit (AST::IfExpr &expr) override
164 : {
165 16 : translated = ASTLoweringIfBlock::translate (expr, &terminated);
166 16 : }
167 :
168 416 : void visit (AST::IfExprConseqElse &expr) override
169 : {
170 416 : translated = ASTLoweringIfBlock::translate (expr, &terminated);
171 416 : }
172 :
173 0 : void visit (AST::IfLetExpr &expr) override
174 : {
175 0 : translated = ASTLoweringIfLetBlock::translate (expr);
176 0 : }
177 :
178 1 : void visit (AST::IfLetExprConseqElse &expr) override
179 : {
180 1 : translated = ASTLoweringIfLetBlock::translate (expr);
181 1 : }
182 :
183 2006 : void visit (AST::BlockExpr &expr) override
184 : {
185 2006 : translated = ASTLoweringBlock::translate (expr, &terminated);
186 2006 : }
187 :
188 0 : void visit (AST::UnsafeBlockExpr &expr) override
189 : {
190 0 : translated = ASTLoweringBlock::translate (expr, &terminated);
191 0 : }
192 :
193 314 : void visit (AST::LoopExpr &expr) override
194 : {
195 314 : HIR::BlockExpr *loop_block
196 314 : = ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
197 :
198 314 : tl::optional<HIR::LoopLabel> loop_label = tl::nullopt;
199 314 : if (expr.has_loop_label ())
200 46 : loop_label = lower_loop_label (expr.get_loop_label ());
201 :
202 314 : auto crate_num = mappings.crate.get_current_crate ();
203 628 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
204 314 : mappings.get_next_hir_id (crate_num),
205 314 : UNKNOWN_LOCAL_DEFID);
206 :
207 314 : translated
208 314 : = new HIR::LoopExpr (mapping,
209 314 : std::unique_ptr<HIR::BlockExpr> (loop_block),
210 : expr.get_locus (), std::move (loop_label),
211 628 : expr.get_outer_attrs ());
212 314 : }
213 :
214 : void visit (AST::WhileLoopExpr &expr) override;
215 :
216 : void visit (AST::MatchExpr &expr) override;
217 :
218 : private:
219 9174 : ASTLoweringExprWithBlock ()
220 9174 : : ASTLoweringBase (), translated (nullptr), terminated (false)
221 : {}
222 :
223 : HIR::ExprWithBlock *translated;
224 : bool terminated;
225 : };
226 :
227 : } // namespace HIR
228 : } // namespace Rust
229 :
230 : #endif // RUST_AST_LOWER_BLOCK
|