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_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::UnsafeBlockExpr &expr) override
173 : : {
174 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
175 : 0 : }
176 : 0 : void visit (HIR::LoopExpr &expr) override
177 : : {
178 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
179 : 0 : }
180 : 0 : void visit (HIR::WhileLoopExpr &expr) override
181 : : {
182 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
183 : 0 : }
184 : 0 : void visit (HIR::WhileLetLoopExpr &expr) override
185 : : {
186 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
187 : 0 : }
188 : 0 : void visit (HIR::IfExpr &expr) override
189 : : {
190 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
191 : 0 : }
192 : 0 : void visit (HIR::IfExprConseqElse &expr) override
193 : : {
194 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
195 : 0 : }
196 : 0 : void visit (HIR::MatchExpr &expr) override
197 : : {
198 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
199 : 0 : }
200 : 0 : void visit (HIR::AwaitExpr &expr) override
201 : : {
202 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
203 : 0 : }
204 : 0 : void visit (HIR::AsyncBlockExpr &expr) override
205 : : {
206 : 0 : return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
207 : 0 : }
208 : :
209 : 0 : void visit (HIR::InlineAsm &expr) override {}
210 : 0 : void visit (HIR::LlvmInlineAsm &expr) override {}
211 : :
212 : : protected: // Illegal at this position.
213 : 0 : void visit (HIR::StructExprFieldIdentifier &field) override
214 : : {
215 : 0 : rust_unreachable ();
216 : : }
217 : 0 : void visit (HIR::StructExprFieldIdentifierValue &field) override
218 : : {
219 : 0 : rust_unreachable ();
220 : : }
221 : 0 : void visit (HIR::StructExprFieldIndexValue &field) override
222 : : {
223 : 0 : rust_unreachable ();
224 : : }
225 : 0 : void visit (HIR::ContinueExpr &expr) override { rust_unreachable (); }
226 : 0 : void visit (HIR::BreakExpr &expr) override { rust_unreachable (); }
227 : 0 : void visit (HIR::RangeFromToExpr &expr) override { rust_unreachable (); }
228 : 0 : void visit (HIR::RangeFromExpr &expr) override { rust_unreachable (); }
229 : 0 : void visit (HIR::RangeToExpr &expr) override { rust_unreachable (); }
230 : 0 : void visit (HIR::RangeFullExpr &expr) override { rust_unreachable (); }
231 : 0 : void visit (HIR::RangeFromToInclExpr &expr) override { rust_unreachable (); }
232 : 0 : void visit (HIR::RangeToInclExpr &expr) override { rust_unreachable (); }
233 : 0 : void visit (HIR::ReturnExpr &expr) override { rust_unreachable (); }
234 : : };
235 : :
236 : : } // namespace BIR
237 : : } // namespace Rust
238 : :
239 : : #endif // RUST_BIR_BUILDER_LAZYBOOLEXPR_H
|