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