Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-compile-block.h"
20 : : #include "rust-compile-stmt.h"
21 : : #include "rust-compile-expr.h"
22 : : #include "rust-hir-expr.h"
23 : :
24 : : namespace Rust {
25 : : namespace Compile {
26 : :
27 : 6881 : CompileBlock::CompileBlock (Context *ctx, Bvariable *result)
28 : 6881 : : HIRCompileBase (ctx), translated (nullptr), result (result)
29 : 6881 : {}
30 : :
31 : : tree
32 : 6881 : CompileBlock::compile (HIR::BlockExpr &expr, Context *ctx, Bvariable *result)
33 : : {
34 : 6881 : CompileBlock compiler (ctx, result);
35 : 6881 : compiler.visit (expr);
36 : 6881 : return compiler.translated;
37 : 6881 : }
38 : :
39 : : void
40 : 6881 : CompileBlock::visit (HIR::BlockExpr &expr)
41 : : {
42 : 6881 : fncontext fnctx = ctx->peek_fn ();
43 : 6881 : tree fndecl = fnctx.fndecl;
44 : 6881 : location_t start_location = expr.get_locus ();
45 : 6881 : location_t end_location = expr.get_end_locus ();
46 : :
47 : 6881 : tree enclosing_scope = ctx->peek_enclosing_scope ();
48 : 6881 : tree new_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
49 : : start_location, end_location);
50 : 6881 : ctx->push_block (new_block);
51 : :
52 : 14559 : for (auto &s : expr.get_statements ())
53 : : {
54 : 7678 : auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
55 : 7678 : if (compiled_expr != nullptr)
56 : : {
57 : 4341 : tree s = convert_to_void (compiled_expr, ICV_STATEMENT);
58 : 4341 : ctx->add_statement (s);
59 : : }
60 : : }
61 : :
62 : 6881 : if (expr.has_expr ())
63 : : {
64 : 4068 : tree compiled_expr = CompileExpr::Compile (expr.get_final_expr (), ctx);
65 : 4068 : if (result != nullptr)
66 : : {
67 : 3840 : location_t locus = expr.get_final_expr ().get_locus ();
68 : 3840 : tree result_reference = Backend::var_expression (result, locus);
69 : :
70 : 3840 : tree assignment
71 : 3840 : = Backend::assignment_statement (result_reference, compiled_expr,
72 : : expr.get_locus ());
73 : 3840 : ctx->add_statement (assignment);
74 : : }
75 : : }
76 : 2813 : else if (result != nullptr)
77 : : {
78 : 2434 : location_t locus = expr.get_locus ();
79 : 2434 : tree compiled_expr = unit_expression (expr.get_locus ());
80 : 2434 : tree result_reference = Backend::var_expression (result, locus);
81 : :
82 : 2434 : tree assignment
83 : 2434 : = Backend::assignment_statement (result_reference, compiled_expr,
84 : : expr.get_locus ());
85 : 2434 : ctx->add_statement (assignment);
86 : : }
87 : :
88 : 6881 : ctx->pop_block ();
89 : 6881 : translated = new_block;
90 : 6881 : }
91 : :
92 : : void
93 : 438 : CompileConditionalBlocks::visit (HIR::IfExpr &expr)
94 : : {
95 : 438 : fncontext fnctx = ctx->peek_fn ();
96 : 438 : tree fndecl = fnctx.fndecl;
97 : 438 : tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
98 : 438 : tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
99 : :
100 : 438 : translated = Backend::if_statement (fndecl, condition_expr, then_block, NULL,
101 : : expr.get_locus ());
102 : 438 : }
103 : :
104 : : void
105 : 1062 : CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
106 : : {
107 : 1062 : fncontext fnctx = ctx->peek_fn ();
108 : 1062 : tree fndecl = fnctx.fndecl;
109 : 1062 : tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
110 : 1062 : tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
111 : :
112 : : // else block
113 : 1062 : std::vector<Bvariable *> locals;
114 : 1062 : location_t start_location = expr.get_else_block ().get_locus ();
115 : 1062 : location_t end_location = expr.get_else_block ().get_locus (); // FIXME
116 : 1062 : tree enclosing_scope = ctx->peek_enclosing_scope ();
117 : 1062 : tree else_block = Backend::block (fndecl, enclosing_scope, locals,
118 : : start_location, end_location);
119 : 1062 : ctx->push_block (else_block);
120 : :
121 : 1062 : tree else_stmt_decl
122 : 1062 : = CompileExprWithBlock::compile (&expr.get_else_block (), ctx, result);
123 : :
124 : 1062 : ctx->add_statement (else_stmt_decl);
125 : :
126 : 1062 : ctx->pop_block ();
127 : :
128 : 1062 : translated = Backend::if_statement (fndecl, condition_expr, then_block,
129 : : else_block, expr.get_locus ());
130 : 1062 : }
131 : :
132 : : } // namespace Compile
133 : : } // namespace Rust
|