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