Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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), short_circuit_bb (0)
41 : : {}
42 : :
43 : 0 : PlaceId build (HIR::LazyBooleanExpr &expr)
44 : : {
45 : 0 : PlaceId return_place = take_or_create_return_place (lookup_type (expr));
46 : :
47 : 0 : short_circuit_bb = new_bb ();
48 : 0 : push_assignment (return_place, visit_expr (expr));
49 : 0 : auto final_bb = new_bb ();
50 : 0 : push_goto (final_bb);
51 : :
52 : 0 : ctx.current_bb = short_circuit_bb;
53 : 0 : push_assignment (return_place,
54 : : ctx.place_db.get_constant (lookup_type (expr)));
55 : 0 : push_goto (final_bb);
56 : :
57 : 0 : ctx.current_bb = final_bb;
58 : 0 : return return_place;
59 : : }
60 : :
61 : : protected:
62 : 0 : void visit (HIR::LazyBooleanExpr &expr) override
63 : : {
64 : 0 : auto lhs = visit_expr (*expr.get_lhs ());
65 : 0 : push_switch (move_place (lhs), {short_circuit_bb});
66 : :
67 : 0 : start_new_consecutive_bb ();
68 : 0 : return_place (visit_expr (*expr.get_rhs ()));
69 : 0 : }
70 : 0 : void visit (HIR::GroupedExpr &expr) override
71 : : {
72 : 0 : expr.get_expr_in_parens ()->accept_vis (*this);
73 : 0 : }
74 : :
75 : : protected:
76 : : public:
77 : 0 : void visit (HIR::QualifiedPathInExpression &expr) override
78 : : {
79 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
80 : 0 : }
81 : 0 : void visit (HIR::PathInExpression &expr) override
82 : : {
83 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
84 : 0 : }
85 : 0 : void visit (HIR::ClosureExpr &expr) override
86 : : {
87 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
88 : 0 : }
89 : 0 : void visit (HIR::StructExprStructFields &fields) override
90 : : {
91 : 0 : ExprStmtBuilder (ctx).build (fields);
92 : 0 : }
93 : 0 : void visit (HIR::StructExprStruct &a_struct) override
94 : : {
95 : 0 : ExprStmtBuilder (ctx).build (a_struct);
96 : 0 : }
97 : 0 : void visit (HIR::LiteralExpr &expr) override
98 : : {
99 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
100 : 0 : }
101 : 0 : void visit (HIR::BorrowExpr &expr) override
102 : : {
103 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
104 : 0 : }
105 : 0 : void visit (HIR::DereferenceExpr &expr) override
106 : : {
107 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
108 : 0 : }
109 : 0 : void visit (HIR::ErrorPropagationExpr &expr) override
110 : : {
111 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
112 : 0 : }
113 : 0 : void visit (HIR::NegationExpr &expr) override
114 : : {
115 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
116 : 0 : }
117 : 0 : void visit (HIR::ArithmeticOrLogicalExpr &expr) override
118 : : {
119 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
120 : 0 : }
121 : 0 : void visit (HIR::ComparisonExpr &expr) override
122 : : {
123 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
124 : 0 : }
125 : 0 : void visit (HIR::TypeCastExpr &expr) override
126 : : {
127 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
128 : 0 : }
129 : 0 : void visit (HIR::AssignmentExpr &expr) override
130 : : {
131 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
132 : 0 : }
133 : 0 : void visit (HIR::CompoundAssignmentExpr &expr) override
134 : : {
135 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
136 : 0 : }
137 : 0 : void visit (HIR::ArrayExpr &expr) override
138 : : {
139 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
140 : 0 : }
141 : 0 : void visit (HIR::ArrayIndexExpr &expr) override
142 : : {
143 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
144 : 0 : }
145 : 0 : void visit (HIR::TupleExpr &expr) override
146 : : {
147 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
148 : 0 : }
149 : 0 : void visit (HIR::TupleIndexExpr &expr) override
150 : : {
151 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
152 : 0 : }
153 : 0 : void visit (HIR::CallExpr &expr) override
154 : : {
155 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
156 : 0 : }
157 : 0 : void visit (HIR::MethodCallExpr &expr) override
158 : : {
159 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
160 : 0 : }
161 : 0 : void visit (HIR::FieldAccessExpr &expr) override
162 : : {
163 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
164 : 0 : }
165 : 0 : void visit (HIR::BlockExpr &expr) override
166 : : {
167 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
168 : 0 : }
169 : 0 : void visit (HIR::UnsafeBlockExpr &expr) override
170 : : {
171 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
172 : 0 : }
173 : 0 : void visit (HIR::LoopExpr &expr) override
174 : : {
175 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
176 : 0 : }
177 : 0 : void visit (HIR::WhileLoopExpr &expr) override
178 : : {
179 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
180 : 0 : }
181 : 0 : void visit (HIR::WhileLetLoopExpr &expr) override
182 : : {
183 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
184 : 0 : }
185 : 0 : void visit (HIR::IfExpr &expr) override
186 : : {
187 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
188 : 0 : }
189 : 0 : void visit (HIR::IfExprConseqElse &expr) override
190 : : {
191 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
192 : 0 : }
193 : 0 : void visit (HIR::IfLetExpr &expr) override
194 : : {
195 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
196 : 0 : }
197 : 0 : void visit (HIR::IfLetExprConseqElse &expr) override
198 : : {
199 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
200 : 0 : }
201 : 0 : void visit (HIR::MatchExpr &expr) override
202 : : {
203 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
204 : 0 : }
205 : 0 : void visit (HIR::AwaitExpr &expr) override
206 : : {
207 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
208 : 0 : }
209 : 0 : void visit (HIR::AsyncBlockExpr &expr) override
210 : : {
211 : 0 : return_place (ExprStmtBuilder (ctx).build (expr));
212 : 0 : }
213 : :
214 : : protected: // Illegal at this position.
215 : 0 : void visit (HIR::StructExprFieldIdentifier &field) override
216 : : {
217 : 0 : rust_unreachable ();
218 : : }
219 : 0 : void visit (HIR::StructExprFieldIdentifierValue &field) override
220 : : {
221 : 0 : rust_unreachable ();
222 : : }
223 : 0 : void visit (HIR::StructExprFieldIndexValue &field) override
224 : : {
225 : 0 : rust_unreachable ();
226 : : }
227 : 0 : void visit (HIR::ContinueExpr &expr) override { rust_unreachable (); }
228 : 0 : void visit (HIR::BreakExpr &expr) override { rust_unreachable (); }
229 : 0 : void visit (HIR::RangeFromToExpr &expr) override { rust_unreachable (); }
230 : 0 : void visit (HIR::RangeFromExpr &expr) override { rust_unreachable (); }
231 : 0 : void visit (HIR::RangeToExpr &expr) override { rust_unreachable (); }
232 : 0 : void visit (HIR::RangeFullExpr &expr) override { rust_unreachable (); }
233 : 0 : void visit (HIR::RangeFromToInclExpr &expr) override { rust_unreachable (); }
234 : 0 : void visit (HIR::RangeToInclExpr &expr) override { rust_unreachable (); }
235 : 0 : void visit (HIR::ReturnExpr &expr) override { rust_unreachable (); }
236 : : };
237 : :
238 : : } // namespace BIR
239 : : } // namespace Rust
240 : :
241 : : #endif // RUST_BIR_BUILDER_LAZYBOOLEXPR_H
|