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_BIR_BUILDER_LAZYBOOLEXPR_H
20 : #define RUST_BIR_BUILDER_LAZYBOOLEXPR_H
21 :
22 : #include "rust-bir-builder-internal.h"
23 : #include "rust-bir-builder-expr-stmt.h"
24 : #include "rust-hir-expr.h"
25 :
26 : namespace Rust {
27 : namespace BIR {
28 :
29 : /**
30 : * Special builder is needed to store short-circuiting context for directly
31 : * nested lazy boolean expressions.
32 : */
33 : class LazyBooleanExprBuilder : public AbstractExprBuilder
34 : {
35 : BasicBlockId short_circuit_bb;
36 :
37 : public:
38 0 : explicit LazyBooleanExprBuilder (BuilderContext &ctx,
39 : PlaceId expr_return_place = INVALID_PLACE)
40 0 : : AbstractExprBuilder (ctx, expr_return_place),
41 0 : short_circuit_bb (ENTRY_BASIC_BLOCK)
42 : {}
43 :
44 0 : PlaceId build (HIR::LazyBooleanExpr &expr)
45 : {
46 0 : PlaceId return_place = take_or_create_return_place (lookup_type (expr));
47 :
48 0 : short_circuit_bb = new_bb ();
49 0 : push_assignment (return_place, visit_expr (expr), expr.get_locus ());
50 0 : auto final_bb = new_bb ();
51 0 : push_goto (final_bb);
52 :
53 0 : ctx.current_bb = short_circuit_bb;
54 0 : push_assignment (return_place,
55 : ctx.place_db.get_constant (lookup_type (expr)),
56 : expr.get_locus ());
57 0 : push_goto (final_bb);
58 :
59 0 : ctx.current_bb = final_bb;
60 0 : return return_place;
61 : }
62 :
63 : protected:
64 0 : void visit (HIR::LazyBooleanExpr &expr) override
65 : {
66 0 : auto lhs = visit_expr (expr.get_lhs ());
67 0 : push_switch (move_place (lhs, expr.get_lhs ().get_locus ()),
68 : expr.get_locus (), {short_circuit_bb});
69 :
70 0 : start_new_consecutive_bb ();
71 0 : return_place (visit_expr (expr.get_rhs ()), expr.get_locus ());
72 0 : }
73 0 : void visit (HIR::GroupedExpr &expr) override
74 : {
75 0 : expr.get_expr_in_parens ().accept_vis (*this);
76 0 : }
77 :
78 : protected:
79 : public:
80 0 : void visit (HIR::QualifiedPathInExpression &expr) override
81 : {
82 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
83 0 : }
84 0 : void visit (HIR::PathInExpression &expr) override
85 : {
86 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
87 0 : }
88 0 : void visit (HIR::ClosureExpr &expr) override
89 : {
90 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
91 0 : }
92 0 : void visit (HIR::StructExprStructFields &fields) override
93 : {
94 0 : ExprStmtBuilder (ctx).build (fields);
95 0 : }
96 0 : void visit (HIR::StructExprStruct &a_struct) override
97 : {
98 0 : ExprStmtBuilder (ctx).build (a_struct);
99 0 : }
100 0 : void visit (HIR::LiteralExpr &expr) override
101 : {
102 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
103 0 : }
104 0 : void visit (HIR::BorrowExpr &expr) override
105 : {
106 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
107 0 : }
108 0 : void visit (HIR::DereferenceExpr &expr) override
109 : {
110 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
111 0 : }
112 0 : void visit (HIR::ErrorPropagationExpr &expr) override
113 : {
114 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
115 0 : }
116 0 : void visit (HIR::NegationExpr &expr) override
117 : {
118 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
119 0 : }
120 0 : void visit (HIR::ArithmeticOrLogicalExpr &expr) override
121 : {
122 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
123 0 : }
124 0 : void visit (HIR::ComparisonExpr &expr) override
125 : {
126 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
127 0 : }
128 0 : void visit (HIR::TypeCastExpr &expr) override
129 : {
130 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
131 0 : }
132 0 : void visit (HIR::AssignmentExpr &expr) override
133 : {
134 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
135 0 : }
136 0 : void visit (HIR::CompoundAssignmentExpr &expr) override
137 : {
138 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
139 0 : }
140 0 : void visit (HIR::ArrayExpr &expr) override
141 : {
142 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
143 0 : }
144 0 : void visit (HIR::ArrayIndexExpr &expr) override
145 : {
146 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
147 0 : }
148 0 : void visit (HIR::TupleExpr &expr) override
149 : {
150 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
151 0 : }
152 0 : void visit (HIR::TupleIndexExpr &expr) override
153 : {
154 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
155 0 : }
156 0 : void visit (HIR::CallExpr &expr) override
157 : {
158 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
159 0 : }
160 0 : void visit (HIR::MethodCallExpr &expr) override
161 : {
162 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
163 0 : }
164 0 : void visit (HIR::FieldAccessExpr &expr) override
165 : {
166 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
167 0 : }
168 0 : void visit (HIR::BlockExpr &expr) override
169 : {
170 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
171 0 : }
172 0 : void visit (HIR::AnonConst &expr) override
173 : {
174 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
175 0 : }
176 0 : void visit (HIR::ConstBlock &expr) override
177 : {
178 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
179 0 : }
180 0 : void visit (HIR::UnsafeBlockExpr &expr) override
181 : {
182 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
183 0 : }
184 0 : void visit (HIR::LoopExpr &expr) override
185 : {
186 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
187 0 : }
188 0 : void visit (HIR::WhileLoopExpr &expr) override
189 : {
190 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
191 0 : }
192 0 : void visit (HIR::WhileLetLoopExpr &expr) override
193 : {
194 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
195 0 : }
196 0 : void visit (HIR::IfExpr &expr) override
197 : {
198 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
199 0 : }
200 0 : void visit (HIR::IfExprConseqElse &expr) override
201 : {
202 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
203 0 : }
204 0 : void visit (HIR::MatchExpr &expr) override
205 : {
206 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
207 0 : }
208 0 : void visit (HIR::AwaitExpr &expr) override
209 : {
210 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
211 0 : }
212 0 : void visit (HIR::AsyncBlockExpr &expr) override
213 : {
214 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
215 0 : }
216 :
217 0 : void visit (HIR::InlineAsm &expr) override {}
218 0 : void visit (HIR::LlvmInlineAsm &expr) override {}
219 0 : void visit (HIR::OffsetOf &expr) override {}
220 :
221 : protected: // Illegal at this position.
222 0 : void visit (HIR::StructExprFieldIdentifier &field) override
223 : {
224 0 : rust_unreachable ();
225 : }
226 0 : void visit (HIR::StructExprFieldIdentifierValue &field) override
227 : {
228 0 : rust_unreachable ();
229 : }
230 0 : void visit (HIR::StructExprFieldIndexValue &field) override
231 : {
232 0 : rust_unreachable ();
233 : }
234 0 : void visit (HIR::ContinueExpr &expr) override { rust_unreachable (); }
235 0 : void visit (HIR::BreakExpr &expr) override { rust_unreachable (); }
236 0 : void visit (HIR::RangeFromToExpr &expr) override { rust_unreachable (); }
237 0 : void visit (HIR::RangeFromExpr &expr) override { rust_unreachable (); }
238 0 : void visit (HIR::RangeToExpr &expr) override { rust_unreachable (); }
239 0 : void visit (HIR::RangeFullExpr &expr) override { rust_unreachable (); }
240 0 : void visit (HIR::RangeFromToInclExpr &expr) override { rust_unreachable (); }
241 0 : void visit (HIR::RangeToInclExpr &expr) override { rust_unreachable (); }
242 0 : void visit (HIR::ReturnExpr &expr) override { rust_unreachable (); }
243 : };
244 :
245 : } // namespace BIR
246 : } // namespace Rust
247 :
248 : #endif // RUST_BIR_BUILDER_LAZYBOOLEXPR_H
|