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