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 26926 : class ASTLoweringBlock : public ASTLoweringBase
29 : {
30 : using Rust::HIR::ASTLoweringBase::visit;
31 :
32 : public:
33 23265 : static HIR::BlockExpr *translate (AST::BlockExpr &expr, bool *terminated)
34 : {
35 46530 : ASTLoweringBlock resolver;
36 23265 : expr.normalize_tail_expr ();
37 23265 : expr.accept_vis (resolver);
38 23265 : if (resolver.translated != nullptr)
39 : {
40 23265 : resolver.mappings.insert_hir_expr (resolver.translated);
41 : }
42 :
43 23265 : *terminated = resolver.terminated;
44 23265 : return resolver.translated;
45 23265 : }
46 :
47 3661 : static HIR::UnsafeBlockExpr *translate (AST::UnsafeBlockExpr &expr,
48 : bool *terminated)
49 : {
50 7322 : ASTLoweringBlock resolver;
51 :
52 3661 : HIR::BlockExpr *block
53 3661 : = ASTLoweringBlock::translate (expr.get_block_expr (), terminated);
54 3661 : auto crate_num = resolver.mappings.get_current_crate ();
55 7322 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
56 : resolver.mappings.get_next_hir_id (
57 : crate_num),
58 3661 : UNKNOWN_LOCAL_DEFID);
59 :
60 3661 : HIR::UnsafeBlockExpr *translated
61 : = new HIR::UnsafeBlockExpr (mapping,
62 3661 : std::unique_ptr<HIR::BlockExpr> (block),
63 3661 : expr.get_outer_attrs (), expr.get_locus ());
64 :
65 3661 : resolver.mappings.insert_hir_expr (translated);
66 :
67 3661 : return translated;
68 3661 : }
69 :
70 : void visit (AST::BlockExpr &expr) override;
71 :
72 : private:
73 26926 : ASTLoweringBlock ()
74 26926 : : 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 2490 : static HIR::IfExpr *translate (AST::IfExpr &expr, bool *terminated)
87 : {
88 4980 : ASTLoweringIfBlock resolver;
89 2490 : expr.accept_vis (resolver);
90 2490 : if (resolver.translated != nullptr)
91 : {
92 2490 : resolver.mappings.insert_hir_expr (resolver.translated);
93 : }
94 2490 : *terminated = resolver.terminated;
95 2490 : return resolver.translated;
96 2490 : }
97 :
98 2490 : ~ASTLoweringIfBlock () {}
99 :
100 : void visit (AST::IfExpr &expr) override;
101 :
102 : void visit (AST::IfExprConseqElse &expr) override;
103 :
104 : private:
105 2490 : ASTLoweringIfBlock ()
106 2490 : : 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 29 : static HIR::MatchExpr *translate (AST::IfLetExpr &expr)
119 : {
120 58 : ASTLoweringIfLetBlock resolver;
121 29 : expr.accept_vis (resolver);
122 29 : if (resolver.translated != nullptr)
123 : {
124 29 : resolver.mappings.insert_hir_expr (resolver.translated);
125 : }
126 29 : return resolver.translated;
127 29 : }
128 :
129 29 : ~ASTLoweringIfLetBlock () {}
130 :
131 : void visit (AST::IfLetExpr &expr) override;
132 :
133 : void visit (AST::IfLetExprConseqElse &expr) override;
134 :
135 : private:
136 29 : 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 2543 : static HIR::ExprWithBlock *translate (AST::ExprWithBlock &expr,
150 : bool *terminated)
151 : {
152 5086 : ASTLoweringExprWithBlock resolver;
153 2543 : expr.accept_vis (resolver);
154 2543 : if (resolver.translated != nullptr)
155 2543 : resolver.mappings.insert_hir_expr (resolver.translated);
156 :
157 2543 : *terminated = resolver.terminated;
158 2543 : return resolver.translated;
159 2543 : }
160 :
161 2543 : ~ASTLoweringExprWithBlock () {}
162 :
163 9 : void visit (AST::IfExpr &expr) override
164 : {
165 9 : translated = ASTLoweringIfBlock::translate (expr, &terminated);
166 9 : }
167 :
168 353 : void visit (AST::IfExprConseqElse &expr) override
169 : {
170 353 : translated = ASTLoweringIfBlock::translate (expr, &terminated);
171 353 : }
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 898 : void visit (AST::BlockExpr &expr) override
184 : {
185 898 : translated = ASTLoweringBlock::translate (expr, &terminated);
186 898 : }
187 :
188 0 : void visit (AST::UnsafeBlockExpr &expr) override
189 : {
190 0 : translated = ASTLoweringBlock::translate (expr, &terminated);
191 0 : }
192 :
193 127 : void visit (AST::LoopExpr &expr) override
194 : {
195 127 : HIR::BlockExpr *loop_block
196 127 : = ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
197 :
198 127 : tl::optional<HIR::LoopLabel> loop_label = tl::nullopt;
199 127 : if (expr.has_loop_label ())
200 35 : loop_label = lower_loop_label (expr.get_loop_label ());
201 :
202 127 : auto crate_num = mappings.get_current_crate ();
203 254 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
204 127 : mappings.get_next_hir_id (crate_num),
205 127 : UNKNOWN_LOCAL_DEFID);
206 :
207 127 : translated
208 127 : = new HIR::LoopExpr (mapping,
209 127 : std::unique_ptr<HIR::BlockExpr> (loop_block),
210 : expr.get_locus (), std::move (loop_label),
211 254 : expr.get_outer_attrs ());
212 127 : }
213 :
214 : void visit (AST::WhileLoopExpr &expr) override;
215 :
216 : void visit (AST::MatchExpr &expr) override;
217 :
218 : private:
219 2543 : ASTLoweringExprWithBlock ()
220 2543 : : 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
|