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