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 : #include "rust-ast-lower-expr.h"
20 : #include "optional.h"
21 : #include "rust-ast-lower-base.h"
22 : #include "rust-ast-lower-block.h"
23 : #include "rust-ast-lower-struct-field-expr.h"
24 : #include "rust-ast-lower-pattern.h"
25 : #include "rust-ast-lower-type.h"
26 : #include "rust-ast.h"
27 : #include "rust-builtin-ast-nodes.h"
28 : #include "rust-diagnostics.h"
29 : #include "rust-hir-map.h"
30 : #include "rust-system.h"
31 : #include "tree/rust-hir-expr.h"
32 :
33 : namespace Rust {
34 : namespace HIR {
35 :
36 679404 : ASTLoweringExpr::ASTLoweringExpr ()
37 679404 : : ASTLoweringBase (), translated (nullptr), translated_array_elems (nullptr),
38 679404 : terminated (false)
39 679404 : {}
40 :
41 : HIR::Expr *
42 679404 : ASTLoweringExpr::translate (AST::Expr &expr, bool *terminated)
43 : {
44 679404 : ASTLoweringExpr resolver;
45 679404 : expr.accept_vis (resolver);
46 679404 : if (resolver.translated == nullptr)
47 : {
48 0 : rust_fatal_error (expr.get_locus (), "Failed to lower expr: [%s]",
49 0 : expr.as_string ().c_str ());
50 : return nullptr;
51 : }
52 :
53 679404 : resolver.mappings.hir.exprs.insert (resolver.translated);
54 679404 : resolver.mappings.insert_location (
55 679404 : resolver.translated->get_mappings ().get_hirid (), expr.get_locus ());
56 :
57 679404 : if (terminated != nullptr)
58 55046 : *terminated = resolver.terminated;
59 :
60 679404 : return resolver.translated;
61 679404 : }
62 :
63 : void
64 4608 : ASTLoweringExpr::visit (AST::TupleIndexExpr &expr)
65 : {
66 4608 : HIR::Expr *tuple_expr
67 4608 : = ASTLoweringExpr::translate (expr.get_tuple_expr (), &terminated);
68 :
69 4608 : auto crate_num = mappings.crate.get_current_crate ();
70 9216 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
71 4608 : mappings.get_next_hir_id (crate_num),
72 4608 : UNKNOWN_LOCAL_DEFID);
73 :
74 4608 : translated
75 4608 : = new HIR::TupleIndexExpr (mapping, std::unique_ptr<HIR::Expr> (tuple_expr),
76 4608 : expr.get_tuple_index (), expr.get_outer_attrs (),
77 9216 : expr.get_locus ());
78 4608 : }
79 :
80 : void
81 4583 : ASTLoweringExpr::visit (AST::TupleExpr &expr)
82 : {
83 4583 : std::vector<std::unique_ptr<HIR::Expr>> tuple_elements;
84 4583 : tuple_elements.reserve (expr.get_tuple_elems ().size ());
85 :
86 13043 : for (auto &e : expr.get_tuple_elems ())
87 8460 : tuple_elements.emplace_back (ASTLoweringExpr::translate (*e));
88 :
89 4583 : auto crate_num = mappings.crate.get_current_crate ();
90 9166 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
91 4583 : mappings.get_next_hir_id (crate_num),
92 4583 : UNKNOWN_LOCAL_DEFID);
93 :
94 4583 : translated
95 4583 : = new HIR::TupleExpr (std::move (mapping), std::move (tuple_elements),
96 9166 : expr.get_inner_attrs (), expr.get_outer_attrs (),
97 4583 : expr.get_locus ());
98 4583 : }
99 :
100 : void
101 1901 : ASTLoweringExpr::visit (AST::IfExpr &expr)
102 : {
103 1901 : translated = ASTLoweringIfBlock::translate (expr, &terminated);
104 1901 : }
105 :
106 : void
107 2023 : ASTLoweringExpr::visit (AST::IfExprConseqElse &expr)
108 : {
109 2023 : translated = ASTLoweringIfBlock::translate (expr, &terminated);
110 2023 : }
111 :
112 : void
113 78 : ASTLoweringExpr::visit (AST::IfLetExpr &expr)
114 : {
115 78 : translated = ASTLoweringIfLetBlock::translate (expr);
116 78 : }
117 :
118 : void
119 41 : ASTLoweringExpr::visit (AST::IfLetExprConseqElse &expr)
120 : {
121 41 : translated = ASTLoweringIfLetBlock::translate (expr);
122 41 : }
123 :
124 : void
125 3161 : ASTLoweringExpr::visit (AST::BlockExpr &expr)
126 : {
127 3161 : translated = ASTLoweringBlock::translate (expr, &terminated);
128 3161 : }
129 :
130 : void
131 1132 : ASTLoweringExpr::visit (AST::AnonConst &expr)
132 : {
133 1132 : auto &mappings = Analysis::Mappings::get ();
134 1132 : auto crate_num = mappings.crate.get_current_crate ();
135 2264 : auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
136 : mappings.get_next_hir_id (crate_num),
137 1132 : UNKNOWN_LOCAL_DEFID);
138 :
139 1132 : if (expr.is_deferred ())
140 : {
141 13 : translated = new HIR::AnonConst (std::move (mapping), expr.get_locus ());
142 : }
143 : else
144 : {
145 1119 : auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
146 :
147 2238 : translated = new HIR::AnonConst (std::move (mapping),
148 1119 : std::unique_ptr<Expr> (inner_expr),
149 1119 : expr.get_locus ());
150 : }
151 1132 : }
152 :
153 : void
154 15 : ASTLoweringExpr::visit (AST::ConstBlock &expr)
155 : {
156 15 : auto inner_expr = ASTLoweringExpr::translate (expr.get_const_expr ());
157 :
158 : // we know this will always be an `AnonConst`, or we have an issue. Let's
159 : // assert just to be sure.
160 15 : rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst);
161 15 : auto anon_const = static_cast<AnonConst *> (inner_expr);
162 :
163 15 : auto &mappings = Analysis::Mappings::get ();
164 15 : auto crate_num = mappings.crate.get_current_crate ();
165 30 : auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
166 : mappings.get_next_hir_id (crate_num),
167 15 : UNKNOWN_LOCAL_DEFID);
168 :
169 15 : translated
170 15 : = new HIR::ConstBlock (std::move (mapping), std::move (*anon_const),
171 15 : expr.get_locus (), expr.get_outer_attrs ());
172 15 : }
173 :
174 : void
175 5029 : ASTLoweringExpr::visit (AST::UnsafeBlockExpr &expr)
176 : {
177 5029 : translated = ASTLoweringBlock::translate (expr, &terminated);
178 5029 : }
179 :
180 : void
181 97288 : ASTLoweringExpr::visit (AST::PathInExpression &expr)
182 : {
183 97288 : translated = ASTLowerPathInExpression::translate (expr);
184 97288 : }
185 :
186 : void
187 224 : ASTLoweringExpr::visit (AST::QualifiedPathInExpression &expr)
188 : {
189 224 : translated = ASTLowerQualPathInExpression::translate (expr);
190 224 : }
191 :
192 : void
193 6 : ASTLoweringExpr::visit (AST::BoxExpr &expr)
194 : {
195 6 : HIR::Expr *box_expr = ASTLoweringExpr::translate (expr.get_boxed_expr ());
196 :
197 6 : auto crate_num = mappings.crate.get_current_crate ();
198 12 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
199 6 : mappings.get_next_hir_id (crate_num),
200 6 : UNKNOWN_LOCAL_DEFID);
201 :
202 12 : translated = new HIR::BoxExpr (mapping, expr.get_locus (),
203 6 : std::unique_ptr<HIR::Expr> (box_expr));
204 6 : }
205 :
206 : void
207 1128 : ASTLoweringExpr::visit (AST::ReturnExpr &expr)
208 : {
209 1128 : terminated = true;
210 1128 : HIR::Expr *return_expr
211 1128 : = expr.has_returned_expr ()
212 1128 : ? ASTLoweringExpr::translate (expr.get_returned_expr ())
213 : : nullptr;
214 :
215 1128 : auto crate_num = mappings.crate.get_current_crate ();
216 2256 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
217 1128 : mappings.get_next_hir_id (crate_num),
218 1128 : UNKNOWN_LOCAL_DEFID);
219 :
220 2256 : translated = new HIR::ReturnExpr (mapping, expr.get_locus (),
221 1128 : std::unique_ptr<HIR::Expr> (return_expr));
222 1128 : }
223 :
224 : void
225 75346 : ASTLoweringExpr::visit (AST::CallExpr &expr)
226 : {
227 75346 : HIR::Expr *func = ASTLoweringExpr::translate (expr.get_function_expr ());
228 :
229 75346 : auto const &in_params = expr.get_params ();
230 :
231 75346 : std::vector<std::unique_ptr<HIR::Expr>> params;
232 75346 : params.reserve (in_params.size ());
233 :
234 252836 : for (auto ¶m : in_params)
235 177490 : params.emplace_back (ASTLoweringExpr::translate (*param));
236 :
237 75346 : auto crate_num = mappings.crate.get_current_crate ();
238 75346 : Analysis::NodeMapping mapping (
239 : crate_num, UNKNOWN_NODEID /* this can map back to the AST*/,
240 75346 : mappings.get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
241 :
242 75346 : translated = new HIR::CallExpr (mapping, std::unique_ptr<HIR::Expr> (func),
243 75346 : std::move (params), expr.get_outer_attrs (),
244 150692 : expr.get_locus ());
245 75346 : }
246 :
247 : void
248 29483 : ASTLoweringExpr::visit (AST::MethodCallExpr &expr)
249 : {
250 29483 : HIR::PathExprSegment method_path
251 29483 : = lower_path_expr_seg (expr.get_method_name ());
252 :
253 29483 : HIR::Expr *receiver = ASTLoweringExpr::translate (expr.get_receiver_expr ());
254 :
255 29483 : auto const &in_params = expr.get_params ();
256 29483 : std::vector<std::unique_ptr<HIR::Expr>> params;
257 29483 : params.reserve (in_params.size ());
258 :
259 35637 : for (auto ¶m : in_params)
260 6154 : params.emplace_back (ASTLoweringExpr::translate (*param));
261 :
262 29483 : auto crate_num = mappings.crate.get_current_crate ();
263 58966 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
264 29483 : mappings.get_next_hir_id (crate_num),
265 29483 : UNKNOWN_LOCAL_DEFID);
266 :
267 29483 : translated
268 29483 : = new HIR::MethodCallExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
269 : method_path, std::move (params),
270 58966 : expr.get_outer_attrs (), expr.get_locus ());
271 29483 : }
272 :
273 : void
274 3670 : ASTLoweringExpr::visit (AST::AssignmentExpr &expr)
275 : {
276 3670 : HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
277 3670 : HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
278 :
279 3670 : auto crate_num = mappings.crate.get_current_crate ();
280 7340 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
281 3670 : mappings.get_next_hir_id (crate_num),
282 3670 : UNKNOWN_LOCAL_DEFID);
283 :
284 3670 : translated
285 3670 : = new HIR::AssignmentExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
286 7340 : std::unique_ptr<HIR::Expr> (rhs),
287 3670 : expr.get_locus ());
288 3670 : }
289 :
290 : void
291 148422 : ASTLoweringExpr::visit (AST::IdentifierExpr &expr)
292 : {
293 148422 : auto crate_num = mappings.crate.get_current_crate ();
294 296844 : Analysis::NodeMapping mapping1 (crate_num, expr.get_node_id (),
295 148422 : mappings.get_next_hir_id (crate_num),
296 148422 : UNKNOWN_LOCAL_DEFID);
297 148422 : Analysis::NodeMapping mapping2 (mapping1);
298 :
299 296844 : HIR::PathIdentSegment ident_seg (expr.get_ident ().as_string ());
300 148422 : HIR::PathExprSegment seg (mapping1, ident_seg, expr.get_locus (),
301 296844 : HIR::GenericArgs::create_empty ());
302 296844 : translated = new HIR::PathInExpression (mapping2, {seg}, expr.get_locus (),
303 296844 : false, expr.get_outer_attrs ());
304 148422 : }
305 :
306 : void
307 13225 : ASTLoweringExpr::visit (AST::ArrayExpr &expr)
308 : {
309 13225 : expr.get_array_elems ()->accept_vis (*this);
310 13225 : rust_assert (translated_array_elems != nullptr);
311 13225 : HIR::ArrayElems *elems = translated_array_elems;
312 :
313 13225 : auto crate_num = mappings.crate.get_current_crate ();
314 26450 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
315 13225 : mappings.get_next_hir_id (crate_num),
316 13225 : UNKNOWN_LOCAL_DEFID);
317 :
318 13225 : translated
319 13225 : = new HIR::ArrayExpr (mapping, std::unique_ptr<HIR::ArrayElems> (elems),
320 26450 : expr.get_inner_attrs (), expr.get_outer_attrs (),
321 26450 : expr.get_locus ());
322 13225 : }
323 :
324 : void
325 739 : ASTLoweringExpr::visit (AST::ArrayIndexExpr &expr)
326 : {
327 739 : HIR::Expr *array_expr = ASTLoweringExpr::translate (expr.get_array_expr ());
328 739 : HIR::Expr *array_index_expr
329 739 : = ASTLoweringExpr::translate (expr.get_index_expr ());
330 :
331 739 : auto crate_num = mappings.crate.get_current_crate ();
332 1478 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
333 739 : mappings.get_next_hir_id (crate_num),
334 739 : UNKNOWN_LOCAL_DEFID);
335 :
336 739 : translated
337 739 : = new HIR::ArrayIndexExpr (mapping, std::unique_ptr<HIR::Expr> (array_expr),
338 1478 : std::unique_ptr<HIR::Expr> (array_index_expr),
339 1478 : expr.get_outer_attrs (), expr.get_locus ());
340 739 : }
341 :
342 : void
343 13053 : ASTLoweringExpr::visit (AST::ArrayElemsValues &elems)
344 : {
345 13053 : std::vector<std::unique_ptr<HIR::Expr>> elements;
346 13053 : elements.reserve (elems.get_values ().size ());
347 :
348 136849 : for (auto &elem : elems.get_values ())
349 123796 : elements.emplace_back (ASTLoweringExpr::translate (*elem));
350 :
351 13053 : auto crate_num = mappings.crate.get_current_crate ();
352 13053 : Analysis::NodeMapping mapping (crate_num, elems.get_node_id (),
353 13053 : mappings.get_next_hir_id (crate_num),
354 13053 : UNKNOWN_LOCAL_DEFID);
355 :
356 13053 : translated_array_elems
357 13053 : = new HIR::ArrayElemsValues (mapping, std::move (elements));
358 13053 : }
359 :
360 : void
361 172 : ASTLoweringExpr::visit (AST::ArrayElemsCopied &elems)
362 : {
363 172 : HIR::Expr *element = ASTLoweringExpr::translate (elems.get_elem_to_copy ());
364 172 : HIR::Expr *num_copies = ASTLoweringExpr::translate (elems.get_num_copies ());
365 :
366 172 : auto crate_num = mappings.crate.get_current_crate ();
367 172 : Analysis::NodeMapping mapping (crate_num, elems.get_node_id (),
368 172 : mappings.get_next_hir_id (crate_num),
369 172 : UNKNOWN_LOCAL_DEFID);
370 :
371 172 : translated_array_elems
372 172 : = new HIR::ArrayElemsCopied (mapping, std::unique_ptr<HIR::Expr> (element),
373 344 : std::unique_ptr<HIR::Expr> (num_copies));
374 172 : }
375 :
376 : void
377 202226 : ASTLoweringExpr::visit (AST::LiteralExpr &expr)
378 : {
379 202226 : auto crate_num = mappings.crate.get_current_crate ();
380 404452 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
381 202226 : mappings.get_next_hir_id (crate_num),
382 202226 : UNKNOWN_LOCAL_DEFID);
383 :
384 202226 : HIR::Literal l = lower_literal (expr.get_literal ());
385 202226 : translated = new HIR::LiteralExpr (mapping, std::move (l), expr.get_locus (),
386 404452 : expr.get_outer_attrs ());
387 202226 : }
388 :
389 : void
390 25039 : ASTLoweringExpr::visit (AST::ArithmeticOrLogicalExpr &expr)
391 : {
392 25039 : HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
393 25039 : rust_assert (lhs != nullptr);
394 25039 : HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
395 25039 : rust_assert (rhs != nullptr);
396 :
397 25039 : auto crate_num = mappings.crate.get_current_crate ();
398 50078 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
399 25039 : mappings.get_next_hir_id (crate_num),
400 25039 : UNKNOWN_LOCAL_DEFID);
401 :
402 50078 : translated = new HIR::ArithmeticOrLogicalExpr (
403 25039 : mapping, std::unique_ptr<HIR::Expr> (lhs), std::unique_ptr<HIR::Expr> (rhs),
404 25039 : expr.get_expr_type (), expr.get_locus ());
405 25039 : }
406 :
407 : void
408 6267 : ASTLoweringExpr::visit (AST::ComparisonExpr &expr)
409 : {
410 6267 : HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
411 6267 : rust_assert (lhs != nullptr);
412 6267 : HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
413 6267 : rust_assert (rhs != nullptr);
414 :
415 6267 : auto crate_num = mappings.crate.get_current_crate ();
416 12534 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
417 6267 : mappings.get_next_hir_id (crate_num),
418 6267 : UNKNOWN_LOCAL_DEFID);
419 :
420 6267 : translated
421 6267 : = new HIR::ComparisonExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
422 12534 : std::unique_ptr<HIR::Expr> (rhs),
423 6267 : expr.get_expr_type (), expr.get_locus ());
424 6267 : }
425 :
426 : void
427 1142 : ASTLoweringExpr::visit (AST::LazyBooleanExpr &expr)
428 : {
429 1142 : HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
430 1142 : rust_assert (lhs != nullptr);
431 1142 : HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
432 1142 : rust_assert (rhs != nullptr);
433 :
434 1142 : auto crate_num = mappings.crate.get_current_crate ();
435 2284 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
436 1142 : mappings.get_next_hir_id (crate_num),
437 1142 : UNKNOWN_LOCAL_DEFID);
438 :
439 1142 : translated
440 1142 : = new HIR::LazyBooleanExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
441 2284 : std::unique_ptr<HIR::Expr> (rhs),
442 1142 : expr.get_expr_type (), expr.get_locus ());
443 1142 : }
444 :
445 : void
446 1556 : ASTLoweringExpr::visit (AST::NegationExpr &expr)
447 : {
448 1556 : HIR::Expr *negated_value
449 1556 : = ASTLoweringExpr::translate (expr.get_negated_expr ());
450 :
451 1556 : auto crate_num = mappings.crate.get_current_crate ();
452 3112 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
453 1556 : mappings.get_next_hir_id (crate_num),
454 1556 : UNKNOWN_LOCAL_DEFID);
455 1556 : translated
456 1556 : = new HIR::NegationExpr (mapping,
457 1556 : std::unique_ptr<HIR::Expr> (negated_value),
458 1556 : expr.get_expr_type (), expr.get_outer_attrs (),
459 3112 : expr.get_locus ());
460 1556 : }
461 :
462 : void
463 9147 : ASTLoweringExpr::visit (AST::TypeCastExpr &expr)
464 : {
465 9147 : HIR::Expr *expr_to_cast_to
466 9147 : = ASTLoweringExpr::translate (expr.get_casted_expr ());
467 9147 : HIR::Type *type_to_cast_to
468 9147 : = lower_type_no_bounds (expr.get_type_to_cast_to ());
469 :
470 9147 : auto crate_num = mappings.crate.get_current_crate ();
471 18294 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
472 9147 : mappings.get_next_hir_id (crate_num),
473 9147 : UNKNOWN_LOCAL_DEFID);
474 :
475 9147 : translated
476 9147 : = new HIR::TypeCastExpr (mapping,
477 9147 : std::unique_ptr<HIR::Expr> (expr_to_cast_to),
478 18294 : std::unique_ptr<HIR::Type> (type_to_cast_to),
479 9147 : expr.get_locus ());
480 9147 : }
481 :
482 : void
483 1527 : ASTLoweringExpr::visit (AST::CompoundAssignmentExpr &expr)
484 : {
485 1527 : ArithmeticOrLogicalOperator op;
486 1527 : switch (expr.get_expr_type ())
487 : {
488 : case CompoundAssignmentOperator::ADD:
489 : op = ArithmeticOrLogicalOperator::ADD;
490 : break;
491 : case CompoundAssignmentOperator::SUBTRACT:
492 : op = ArithmeticOrLogicalOperator::SUBTRACT;
493 : break;
494 : case CompoundAssignmentOperator::MULTIPLY:
495 : op = ArithmeticOrLogicalOperator::MULTIPLY;
496 : break;
497 : case CompoundAssignmentOperator::DIVIDE:
498 : op = ArithmeticOrLogicalOperator::DIVIDE;
499 : break;
500 : case CompoundAssignmentOperator::MODULUS:
501 : op = ArithmeticOrLogicalOperator::MODULUS;
502 : break;
503 : case CompoundAssignmentOperator::BITWISE_AND:
504 : op = ArithmeticOrLogicalOperator::BITWISE_AND;
505 : break;
506 : case CompoundAssignmentOperator::BITWISE_OR:
507 : op = ArithmeticOrLogicalOperator::BITWISE_OR;
508 : break;
509 : case CompoundAssignmentOperator::BITWISE_XOR:
510 : op = ArithmeticOrLogicalOperator::BITWISE_XOR;
511 : break;
512 : case CompoundAssignmentOperator::LEFT_SHIFT:
513 : op = ArithmeticOrLogicalOperator::LEFT_SHIFT;
514 : break;
515 : case CompoundAssignmentOperator::RIGHT_SHIFT:
516 : op = ArithmeticOrLogicalOperator::RIGHT_SHIFT;
517 : break;
518 0 : default:
519 0 : rust_unreachable ();
520 : }
521 :
522 1527 : HIR::Expr *asignee_expr = ASTLoweringExpr::translate (expr.get_left_expr ());
523 1527 : HIR::Expr *value = ASTLoweringExpr::translate (expr.get_right_expr ());
524 :
525 1527 : auto crate_num = mappings.crate.get_current_crate ();
526 3054 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
527 1527 : mappings.get_next_hir_id (crate_num),
528 1527 : UNKNOWN_LOCAL_DEFID);
529 :
530 3054 : translated = new HIR::CompoundAssignmentExpr (
531 1527 : mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
532 3054 : std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
533 1527 : }
534 :
535 : void
536 105 : ASTLoweringExpr::visit (AST::StructExprStruct &struct_expr)
537 : {
538 105 : HIR::PathInExpression *path
539 105 : = ASTLowerPathInExpression::translate (struct_expr.get_struct_name ());
540 105 : HIR::PathInExpression copied_path (*path);
541 105 : delete path;
542 :
543 105 : auto crate_num = mappings.crate.get_current_crate ();
544 210 : Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
545 105 : mappings.get_next_hir_id (crate_num),
546 105 : UNKNOWN_LOCAL_DEFID);
547 :
548 210 : translated = new HIR::StructExprStruct (mapping, copied_path,
549 105 : struct_expr.get_inner_attrs (),
550 105 : struct_expr.get_outer_attrs (),
551 105 : struct_expr.get_locus ());
552 105 : }
553 :
554 : void
555 1840 : ASTLoweringExpr::visit (AST::StructExprStructFields &struct_expr)
556 : {
557 : // bit of a hack for now
558 1840 : HIR::PathInExpression *path
559 1840 : = ASTLowerPathInExpression::translate (struct_expr.get_struct_name ());
560 1840 : HIR::PathInExpression copied_path (*path);
561 1840 : delete path;
562 :
563 1840 : tl::optional<std::unique_ptr<HIR::StructBase>> base = tl::nullopt;
564 1840 : if (struct_expr.has_struct_base ())
565 : {
566 66 : HIR::Expr *translated_base = ASTLoweringExpr::translate (
567 66 : struct_expr.get_struct_base ().get_base_struct ());
568 66 : base = tl::optional<std::unique_ptr<HIR::StructBase>> (
569 132 : std::make_unique<StructBase> (
570 132 : std::unique_ptr<HIR::Expr> (translated_base)));
571 : }
572 :
573 1840 : auto const &in_fields = struct_expr.get_fields ();
574 :
575 1840 : std::vector<std::unique_ptr<HIR::StructExprField>> fields;
576 1840 : fields.reserve (in_fields.size ());
577 :
578 5058 : for (auto &field : in_fields)
579 3218 : fields.emplace_back (ASTLowerStructExprField::translate (*field));
580 :
581 1840 : auto crate_num = mappings.crate.get_current_crate ();
582 3680 : Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
583 1840 : mappings.get_next_hir_id (crate_num),
584 1840 : UNKNOWN_LOCAL_DEFID);
585 :
586 1840 : translated
587 1840 : = new HIR::StructExprStructFields (mapping, copied_path, std::move (fields),
588 : struct_expr.get_locus (),
589 : std::move (base),
590 1840 : struct_expr.get_inner_attrs (),
591 3746 : struct_expr.get_outer_attrs ());
592 1906 : }
593 :
594 : void
595 7573 : ASTLoweringExpr::visit (AST::GroupedExpr &expr)
596 : {
597 7573 : HIR::Expr *paren_expr
598 7573 : = ASTLoweringExpr::translate (expr.get_expr_in_parens ());
599 :
600 7573 : auto crate_num = mappings.crate.get_current_crate ();
601 15146 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
602 7573 : mappings.get_next_hir_id (crate_num),
603 7573 : UNKNOWN_LOCAL_DEFID);
604 :
605 7573 : translated
606 7573 : = new HIR::GroupedExpr (mapping, std::unique_ptr<HIR::Expr> (paren_expr),
607 15146 : expr.get_inner_attrs (), expr.get_outer_attrs (),
608 15146 : expr.get_locus ());
609 7573 : }
610 :
611 : void
612 8187 : ASTLoweringExpr::visit (AST::FieldAccessExpr &expr)
613 : {
614 8187 : HIR::Expr *receiver = ASTLoweringExpr::translate (expr.get_receiver_expr ());
615 :
616 8187 : auto crate_num = mappings.crate.get_current_crate ();
617 16374 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
618 8187 : mappings.get_next_hir_id (crate_num),
619 8187 : UNKNOWN_LOCAL_DEFID);
620 8187 : translated
621 8187 : = new HIR::FieldAccessExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
622 16374 : expr.get_field_name (), expr.get_outer_attrs (),
623 16374 : expr.get_locus ());
624 8187 : }
625 :
626 : void
627 314 : ASTLoweringExpr::visit (AST::LoopExpr &expr)
628 : {
629 314 : translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
630 314 : }
631 :
632 : void
633 196 : ASTLoweringExpr::visit (AST::WhileLoopExpr &expr)
634 : {
635 196 : translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
636 196 : }
637 :
638 : void
639 273 : ASTLoweringExpr::visit (AST::BreakExpr &expr)
640 : {
641 273 : tl::optional<HIR::Lifetime> break_label = tl::nullopt;
642 273 : if (expr.has_label ())
643 33 : break_label = lower_lifetime (expr.get_label_unchecked ().get_lifetime ());
644 :
645 273 : HIR::Expr *break_expr
646 273 : = expr.has_break_expr ()
647 273 : ? ASTLoweringExpr::translate (expr.get_break_expr_unchecked ())
648 : : nullptr;
649 :
650 273 : auto crate_num = mappings.crate.get_current_crate ();
651 546 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
652 273 : mappings.get_next_hir_id (crate_num),
653 273 : UNKNOWN_LOCAL_DEFID);
654 :
655 273 : translated
656 273 : = new HIR::BreakExpr (mapping, expr.get_locus (), std ::move (break_label),
657 273 : std::unique_ptr<HIR::Expr> (break_expr),
658 546 : expr.get_outer_attrs ());
659 273 : }
660 :
661 : void
662 42 : ASTLoweringExpr::visit (AST::ContinueExpr &expr)
663 : {
664 42 : tl::optional<HIR::Lifetime> break_label;
665 42 : if (expr.has_label ())
666 12 : break_label = lower_lifetime (expr.get_label_unchecked ());
667 :
668 42 : auto crate_num = mappings.crate.get_current_crate ();
669 84 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
670 42 : mappings.get_next_hir_id (crate_num),
671 42 : UNKNOWN_LOCAL_DEFID);
672 :
673 42 : translated
674 42 : = new HIR::ContinueExpr (mapping, expr.get_locus (),
675 84 : std ::move (break_label), expr.get_outer_attrs ());
676 42 : }
677 :
678 : void
679 5190 : ASTLoweringExpr::visit (AST::BorrowExpr &expr)
680 : {
681 5190 : HIR::Expr *borrow_lvalue
682 5190 : = ASTLoweringExpr::translate (expr.get_borrowed_expr ());
683 :
684 5190 : auto crate_num = mappings.crate.get_current_crate ();
685 10380 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
686 5190 : mappings.get_next_hir_id (crate_num),
687 5190 : UNKNOWN_LOCAL_DEFID);
688 :
689 5190 : auto *borrow_expr
690 5190 : = new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
691 : expr.get_mutability (), expr.is_raw_borrow (),
692 5190 : expr.get_outer_attrs (), expr.get_locus ());
693 :
694 5190 : if (expr.get_is_double_borrow ())
695 : {
696 38 : NodeId artificial_double_borrow_id = mappings.get_next_node_id ();
697 38 : Analysis::NodeMapping mapping (crate_num, artificial_double_borrow_id,
698 38 : mappings.get_next_hir_id (crate_num),
699 38 : UNKNOWN_LOCAL_DEFID);
700 :
701 38 : borrow_expr
702 38 : = new HIR::BorrowExpr (mapping,
703 38 : std::unique_ptr<HIR::Expr> (borrow_expr),
704 : expr.get_mutability (), expr.is_raw_borrow (),
705 76 : expr.get_outer_attrs (), expr.get_locus ());
706 : }
707 :
708 5190 : translated = borrow_expr;
709 5190 : }
710 :
711 : void
712 9587 : ASTLoweringExpr::visit (AST::DereferenceExpr &expr)
713 : {
714 9587 : HIR::Expr *dref_lvalue
715 9587 : = ASTLoweringExpr::translate (expr.get_dereferenced_expr ());
716 :
717 9587 : auto crate_num = mappings.crate.get_current_crate ();
718 19174 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
719 9587 : mappings.get_next_hir_id (crate_num),
720 9587 : UNKNOWN_LOCAL_DEFID);
721 :
722 9587 : translated
723 9587 : = new HIR::DereferenceExpr (mapping,
724 9587 : std::unique_ptr<HIR::Expr> (dref_lvalue),
725 19174 : expr.get_outer_attrs (), expr.get_locus ());
726 9587 : }
727 :
728 : void
729 6225 : ASTLoweringExpr::visit (AST::MatchExpr &expr)
730 : {
731 6225 : translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
732 6225 : }
733 :
734 : void
735 195 : ASTLoweringExpr::visit (AST::RangeFromToExpr &expr)
736 : {
737 195 : auto crate_num = mappings.crate.get_current_crate ();
738 390 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
739 195 : mappings.get_next_hir_id (crate_num),
740 195 : UNKNOWN_LOCAL_DEFID);
741 :
742 195 : HIR::Expr *range_from = ASTLoweringExpr::translate (expr.get_from_expr ());
743 195 : HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ());
744 :
745 195 : translated
746 195 : = new HIR::RangeFromToExpr (mapping,
747 195 : std::unique_ptr<HIR::Expr> (range_from),
748 390 : std::unique_ptr<HIR::Expr> (range_to),
749 195 : expr.get_locus ());
750 195 : }
751 :
752 : void
753 63 : ASTLoweringExpr::visit (AST::RangeFromExpr &expr)
754 : {
755 63 : auto crate_num = mappings.crate.get_current_crate ();
756 126 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
757 63 : mappings.get_next_hir_id (crate_num),
758 63 : UNKNOWN_LOCAL_DEFID);
759 :
760 63 : HIR::Expr *range_from = ASTLoweringExpr::translate (expr.get_from_expr ());
761 :
762 63 : translated
763 63 : = new HIR::RangeFromExpr (mapping, std::unique_ptr<HIR::Expr> (range_from),
764 63 : expr.get_locus ());
765 63 : }
766 :
767 : void
768 118 : ASTLoweringExpr::visit (AST::RangeToExpr &expr)
769 : {
770 118 : auto crate_num = mappings.crate.get_current_crate ();
771 236 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
772 118 : mappings.get_next_hir_id (crate_num),
773 118 : UNKNOWN_LOCAL_DEFID);
774 :
775 118 : HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ());
776 :
777 118 : translated
778 118 : = new HIR::RangeToExpr (mapping, std::unique_ptr<HIR::Expr> (range_to),
779 118 : expr.get_locus ());
780 118 : }
781 :
782 : void
783 53 : ASTLoweringExpr::visit (AST::RangeFullExpr &expr)
784 : {
785 53 : auto crate_num = mappings.crate.get_current_crate ();
786 106 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
787 53 : mappings.get_next_hir_id (crate_num),
788 53 : UNKNOWN_LOCAL_DEFID);
789 :
790 53 : translated = new HIR::RangeFullExpr (mapping, expr.get_locus ());
791 53 : }
792 :
793 : void
794 13 : ASTLoweringExpr::visit (AST::RangeFromToInclExpr &expr)
795 : {
796 13 : auto crate_num = mappings.crate.get_current_crate ();
797 26 : Analysis::NodeMapping path_mapping (crate_num, mappings.get_next_node_id (),
798 13 : mappings.get_next_hir_id (crate_num),
799 13 : UNKNOWN_LOCAL_DEFID);
800 26 : Analysis::NodeMapping call_mapping (crate_num, expr.get_node_id (),
801 13 : mappings.get_next_hir_id (crate_num),
802 13 : UNKNOWN_LOCAL_DEFID);
803 :
804 13 : HIR::Expr *func
805 : = new HIR::PathInExpression (path_mapping,
806 : LangItem::Kind::RANGE_INCLUSIVE_NEW,
807 13 : expr.get_locus (), false);
808 :
809 13 : HIR::Expr *range_from = ASTLoweringExpr::translate (expr.get_from_expr ());
810 13 : HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ());
811 :
812 13 : std::vector<std::unique_ptr<HIR::Expr>> params;
813 13 : params.reserve (2);
814 13 : params.emplace_back (std::unique_ptr<HIR::Expr> (range_from));
815 13 : params.emplace_back (std::unique_ptr<HIR::Expr> (range_to));
816 :
817 13 : translated
818 13 : = new HIR::CallExpr (call_mapping, std::unique_ptr<HIR::Expr> (func),
819 13 : std::move (params), expr.get_outer_attrs (),
820 26 : expr.get_locus ());
821 13 : }
822 :
823 : void
824 337 : ASTLoweringExpr::visit (AST::ClosureExprInner &expr)
825 : {
826 337 : HIR::Expr *closure_expr
827 337 : = ASTLoweringExpr::translate (expr.get_definition_expr ());
828 :
829 337 : std::vector<HIR::ClosureParam> closure_params;
830 337 : closure_params.reserve (expr.get_params ().size ());
831 :
832 720 : for (auto ¶m : expr.get_params ())
833 383 : closure_params.emplace_back (lower_closure_param (param));
834 :
835 337 : auto crate_num = mappings.crate.get_current_crate ();
836 674 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
837 337 : mappings.get_next_hir_id (crate_num),
838 337 : mappings.get_next_localdef_id (crate_num));
839 :
840 337 : translated
841 337 : = new HIR::ClosureExpr (mapping, std::move (closure_params),
842 : nullptr /* closure_return_type */,
843 337 : std::unique_ptr<HIR::Expr> (closure_expr),
844 337 : expr.get_has_move (), expr.get_outer_attrs (),
845 337 : expr.get_locus ());
846 337 : }
847 :
848 : void
849 31 : ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
850 : {
851 31 : HIR::Type *closure_return_type = nullptr;
852 31 : HIR::Expr *closure_expr
853 31 : = ASTLoweringExpr::translate (expr.get_definition_expr ());
854 :
855 31 : std::vector<HIR::ClosureParam> closure_params;
856 31 : closure_params.reserve (expr.get_params ().size ());
857 :
858 69 : for (auto ¶m : expr.get_params ())
859 38 : closure_params.emplace_back (lower_closure_param (param));
860 :
861 31 : auto crate_num = mappings.crate.get_current_crate ();
862 62 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
863 31 : mappings.get_next_hir_id (crate_num),
864 31 : mappings.get_next_localdef_id (crate_num));
865 :
866 31 : translated
867 31 : = new HIR::ClosureExpr (mapping, std::move (closure_params),
868 93 : std::unique_ptr<HIR::Type> (closure_return_type),
869 62 : std::unique_ptr<HIR::Expr> (closure_expr),
870 31 : expr.get_has_move (), expr.get_outer_attrs (),
871 62 : expr.get_locus ());
872 31 : }
873 :
874 : HIR::InlineAsmOperand
875 10 : translate_operand_in (const AST::InlineAsmOperand &operand)
876 : {
877 10 : auto in_value = operand.get_in ();
878 :
879 10 : struct HIR::InlineAsmOperand::In in (
880 : in_value.reg,
881 10 : std::unique_ptr<Expr> (ASTLoweringExpr::translate (*in_value.expr.get ())));
882 10 : return in;
883 10 : }
884 :
885 : HIR::InlineAsmOperand
886 17 : translate_operand_out (const AST::InlineAsmOperand &operand)
887 : {
888 17 : auto out_value = operand.get_out ();
889 17 : struct HIR::InlineAsmOperand::Out out (out_value.reg, out_value.late,
890 17 : std::unique_ptr<Expr> (
891 : ASTLoweringExpr::translate (
892 17 : *out_value.expr.get ())));
893 17 : return out;
894 17 : }
895 :
896 : HIR::InlineAsmOperand
897 0 : translate_operand_inout (const AST::InlineAsmOperand &operand)
898 : {
899 0 : auto inout_value = operand.get_in_out ();
900 0 : struct HIR::InlineAsmOperand::InOut inout (inout_value.reg, inout_value.late,
901 0 : std::unique_ptr<Expr> (
902 : ASTLoweringExpr::translate (
903 0 : *inout_value.expr.get ())));
904 0 : return inout;
905 0 : }
906 :
907 : HIR::InlineAsmOperand
908 2 : translate_operand_split_in_out (const AST::InlineAsmOperand &operand)
909 : {
910 2 : auto split_in_out_value = operand.get_split_in_out ();
911 2 : struct HIR::InlineAsmOperand::SplitInOut split_in_out (
912 : split_in_out_value.reg, split_in_out_value.late,
913 2 : std::unique_ptr<Expr> (
914 2 : ASTLoweringExpr::translate (*split_in_out_value.in_expr.get ())),
915 2 : std::unique_ptr<Expr> (
916 2 : ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ())));
917 2 : return split_in_out;
918 2 : }
919 :
920 : HIR::InlineAsmOperand
921 0 : translate_operand_const (const AST::InlineAsmOperand &operand)
922 : {
923 0 : auto const_value = operand.get_const ();
924 :
925 0 : auto inner_expr = ASTLoweringExpr::translate (const_value.anon_const);
926 :
927 : // Like `ConstBlock`, we know this should only be an `AnonConst` - let's
928 : // assert to make sure and static cast
929 0 : rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst);
930 :
931 0 : auto anon_const = static_cast<AnonConst *> (inner_expr);
932 :
933 0 : return HIR::InlineAsmOperand::Const{*anon_const};
934 0 : }
935 :
936 : HIR::InlineAsmOperand
937 0 : translate_operand_sym (const AST::InlineAsmOperand &operand)
938 : {
939 0 : auto sym_value = operand.get_sym ();
940 0 : struct HIR::InlineAsmOperand::Sym sym (std::unique_ptr<Expr> (
941 0 : ASTLoweringExpr::translate (*sym_value.expr.get ())));
942 0 : return sym;
943 0 : }
944 : HIR::InlineAsmOperand
945 0 : translate_operand_label (const AST::InlineAsmOperand &operand)
946 : {
947 0 : auto label_value = operand.get_label ();
948 0 : struct HIR::InlineAsmOperand::Label label (label_value.label_name,
949 0 : std::unique_ptr<Expr> (
950 : ASTLoweringExpr::translate (
951 0 : *label_value.expr.get ())));
952 0 : return label;
953 0 : }
954 : HIR::InlineAsmOperand
955 29 : from_operand (const AST::InlineAsmOperand &operand)
956 : {
957 29 : using RegisterType = AST::InlineAsmOperand::RegisterType;
958 29 : auto type = operand.get_register_type ();
959 :
960 : /*In,*/
961 : /*Out,*/
962 : /*InOut,*/
963 : /*SplitInOut,*/
964 : /*Const,*/
965 : /*Sym,*/
966 : /*Label,*/
967 29 : switch (type)
968 : {
969 10 : case RegisterType::In:
970 10 : return translate_operand_in (operand);
971 17 : case RegisterType::Out:
972 17 : return translate_operand_out (operand);
973 0 : case RegisterType::InOut:
974 0 : return translate_operand_inout (operand);
975 2 : case RegisterType::SplitInOut:
976 2 : return translate_operand_split_in_out (operand);
977 0 : case RegisterType::Const:
978 0 : return translate_operand_const (operand);
979 0 : case RegisterType::Sym:
980 0 : return translate_operand_sym (operand);
981 0 : case RegisterType::Label:
982 0 : return translate_operand_label (operand);
983 0 : default:
984 0 : rust_unreachable ();
985 : }
986 : }
987 : void
988 27 : ASTLoweringExpr::visit (AST::InlineAsm &expr)
989 : {
990 27 : auto crate_num = mappings.crate.get_current_crate ();
991 54 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
992 27 : mappings.get_next_hir_id (crate_num),
993 27 : mappings.get_next_localdef_id (crate_num));
994 :
995 27 : std::vector<HIR::InlineAsmOperand> hir_operands;
996 27 : const std::vector<AST::InlineAsmOperand> &ast_operands = expr.get_operands ();
997 : /*int ast_operands_size = ast_operands.size ();*/
998 56 : for (auto &operand : ast_operands)
999 : {
1000 29 : hir_operands.push_back (from_operand (operand));
1001 : }
1002 : /*int hir_operands_size = hir_operands.size ();*/
1003 :
1004 : /*rust_debug ("{bdbt} : There are %d ast operands prelowering and %d hir "*/
1005 : /* "operands after lowering\n",*/
1006 : /* ast_operands_size, hir_operands_size);*/
1007 27 : translated
1008 54 : = new HIR::InlineAsm (expr.get_locus (), expr.is_global_asm,
1009 54 : expr.get_template_ (), expr.get_template_strs (),
1010 27 : hir_operands, expr.get_clobber_abi (),
1011 108 : expr.get_options (), mapping);
1012 27 : }
1013 :
1014 : namespace {
1015 :
1016 : tl::optional<std::string>
1017 28 : convert_template_str (const std::string &in_template)
1018 : {
1019 28 : std::string out_template;
1020 28 : auto it = in_template.cbegin ();
1021 :
1022 396 : while (it != in_template.cend ())
1023 : {
1024 368 : if (*it == '$')
1025 : {
1026 52 : it++;
1027 52 : if (it == in_template.cend ())
1028 : {
1029 0 : return tl::nullopt;
1030 : }
1031 52 : else if (*it >= '0' && *it <= '9')
1032 : {
1033 36 : out_template.push_back ('%');
1034 36 : out_template.push_back (*it);
1035 36 : it++;
1036 : }
1037 16 : else if (*it == '$')
1038 : {
1039 0 : out_template.push_back ('$');
1040 0 : it++;
1041 : }
1042 16 : else if (*it == '{')
1043 : {
1044 16 : it++;
1045 : // converting
1046 : // v
1047 : // ${123:abc}
1048 : // to
1049 : // %abc123
1050 16 : auto num_it = it;
1051 16 : while (true)
1052 : {
1053 32 : if (it == in_template.cend ())
1054 0 : return tl::nullopt;
1055 32 : if (*it == ':')
1056 : break;
1057 16 : it++;
1058 : }
1059 : auto colon_it = it;
1060 32 : while (true)
1061 : {
1062 48 : if (it == in_template.cend ())
1063 0 : return tl::nullopt;
1064 48 : if (*it == '}')
1065 : break;
1066 32 : it++;
1067 : }
1068 : // output
1069 16 : out_template.push_back ('%');
1070 16 : out_template.append (colon_it + 1, it);
1071 16 : out_template.append (num_it, colon_it);
1072 : // increment past '}'
1073 16 : it++;
1074 : }
1075 : else
1076 : {
1077 0 : return tl::nullopt;
1078 : }
1079 : }
1080 316 : else if (*it == '%' || *it == '{' || *it == '|' || *it == '}')
1081 : {
1082 0 : out_template.push_back ('%');
1083 0 : out_template.push_back (*it);
1084 0 : it++;
1085 : }
1086 : else
1087 : {
1088 316 : out_template.push_back (*it);
1089 316 : it++;
1090 : }
1091 : }
1092 :
1093 28 : return out_template;
1094 28 : }
1095 :
1096 : // We're not really supporting llvm_asm, only the bare minimum for libcore
1097 : // ex: llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
1098 : bool
1099 14 : check_llvm_asm_support (const AST::LlvmInlineAsm &expr)
1100 : {
1101 : // TODO: more checks/constraint rewriting?
1102 :
1103 28 : if (!convert_template_str (expr.get_template ().symbol).has_value ())
1104 : return false;
1105 :
1106 : // TODO: check output constraints?
1107 :
1108 : // prohibit commas
1109 : // GCC uses them to list multiple options for constraints (?)
1110 : // while LLVM uses them for inout args (?)
1111 29 : for (auto &input : expr.get_inputs ())
1112 15 : if (input.constraint.find (',') != std::string::npos)
1113 14 : return false;
1114 :
1115 : // TODO: check clobbers?
1116 :
1117 : // no alignstack or intel support
1118 14 : if (expr.is_stack_aligned ())
1119 : return false;
1120 14 : if (expr.get_dialect () == AST::LlvmInlineAsm::Dialect::Intel)
1121 0 : return false;
1122 :
1123 : return true;
1124 : }
1125 :
1126 : } // namespace
1127 :
1128 : void
1129 14 : ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
1130 : {
1131 14 : if (!check_llvm_asm_support (expr))
1132 : {
1133 0 : rust_error_at (expr.get_locus (), "unsupported %qs construct",
1134 : "llvm_asm");
1135 0 : rust_inform (
1136 0 : expr.get_locus (),
1137 : "%<llvm_asm%> has been replaced with %<asm%>, gccrs only supports a "
1138 : "subset of %<llvm_asm%> to compile libcore");
1139 : }
1140 :
1141 14 : auto crate_num = mappings.crate.get_current_crate ();
1142 28 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
1143 14 : mappings.get_next_hir_id (crate_num),
1144 14 : mappings.get_next_localdef_id (crate_num));
1145 :
1146 14 : std::vector<LlvmOperand> inputs;
1147 14 : inputs.reserve (expr.get_inputs ().size ());
1148 :
1149 14 : std::vector<LlvmOperand> outputs;
1150 14 : outputs.reserve (expr.get_outputs ().size ());
1151 :
1152 29 : for (auto i : expr.get_inputs ())
1153 : {
1154 15 : std::unique_ptr<Expr> inner_expr
1155 15 : = std::unique_ptr<Expr> (translate (*i.expr.get ()));
1156 15 : inputs.emplace_back (i.constraint, std::move (inner_expr));
1157 30 : }
1158 :
1159 31 : for (auto o : expr.get_outputs ())
1160 : {
1161 17 : std::unique_ptr<Expr> inner_expr
1162 17 : = std::unique_ptr<Expr> (translate (*o.expr.get ()));
1163 17 : outputs.emplace_back (o.constraint, std::move (inner_expr));
1164 34 : }
1165 :
1166 14 : HIR::LlvmInlineAsm::Options options{expr.is_volatile (),
1167 14 : expr.is_stack_aligned (),
1168 14 : expr.get_dialect ()};
1169 :
1170 14 : auto new_template = expr.get_template ();
1171 14 : new_template.symbol
1172 14 : = convert_template_str (new_template.symbol).value_or (std::string ());
1173 :
1174 14 : rust_debug_fmt_at (expr.get_locus (),
1175 : "converting %<llvm_asm%> template %qs to %qs",
1176 14 : expr.get_template ().symbol.c_str (),
1177 : new_template.symbol.c_str ());
1178 :
1179 14 : translated
1180 28 : = new HIR::LlvmInlineAsm (expr.get_locus (), inputs, outputs,
1181 14 : std::move (new_template), expr.get_clobbers (),
1182 14 : options, expr.get_outer_attrs (), mapping);
1183 14 : }
1184 :
1185 : void
1186 0 : ASTLoweringExpr::visit (AST::FormatArgs &fmt)
1187 : {
1188 0 : rust_sorry_at (fmt.get_locus (),
1189 : "FormatArgs lowering is not implemented yet");
1190 0 : }
1191 :
1192 : void
1193 15 : ASTLoweringExpr::visit (AST::OffsetOf &offset_of)
1194 : {
1195 15 : auto type = std::unique_ptr<Type> (
1196 15 : ASTLoweringType::translate (offset_of.get_type ()));
1197 :
1198 15 : auto crate_num = mappings.crate.get_current_crate ();
1199 30 : Analysis::NodeMapping mapping (crate_num, offset_of.get_node_id (),
1200 15 : mappings.get_next_hir_id (crate_num),
1201 15 : mappings.get_next_localdef_id (crate_num));
1202 :
1203 15 : translated = new HIR::OffsetOf (std::move (type), offset_of.get_field (),
1204 15 : mapping, offset_of.get_locus ());
1205 15 : }
1206 :
1207 : } // namespace HIR
1208 : } // namespace Rust
|