1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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
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
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/>.
19 #include "rust-compile-block.h"
20 #include "rust-compile-stmt.h"
21 #include "rust-compile-expr.h"
26 CompileBlock::CompileBlock (Context
*ctx
, Bvariable
*result
)
27 : HIRCompileBase (ctx
), translated (nullptr), result (result
)
31 CompileBlock::compile (HIR::BlockExpr
*expr
, Context
*ctx
, Bvariable
*result
)
33 CompileBlock
compiler (ctx
, result
);
34 compiler
.visit (*expr
);
35 return compiler
.translated
;
39 CompileBlock::visit (HIR::BlockExpr
&expr
)
41 fncontext fnctx
= ctx
->peek_fn ();
42 tree fndecl
= fnctx
.fndecl
;
43 location_t start_location
= expr
.get_locus ();
44 location_t end_location
= expr
.get_end_locus ();
46 tree enclosing_scope
= ctx
->peek_enclosing_scope ();
47 tree new_block
= Backend::block (fndecl
, enclosing_scope
, {} /*locals*/,
48 start_location
, end_location
);
49 ctx
->push_block (new_block
);
51 for (auto &s
: expr
.get_statements ())
53 auto compiled_expr
= CompileStmt::Compile (s
.get (), ctx
);
54 if (compiled_expr
!= nullptr)
56 tree s
= convert_to_void (compiled_expr
, ICV_STATEMENT
);
57 ctx
->add_statement (s
);
63 tree compiled_expr
= CompileExpr::Compile (expr
.expr
.get (), ctx
);
64 if (result
!= nullptr)
66 location_t locus
= expr
.get_final_expr ()->get_locus ();
67 tree result_reference
= Backend::var_expression (result
, locus
);
70 = Backend::assignment_statement (result_reference
, compiled_expr
,
72 ctx
->add_statement (assignment
);
75 else if (result
!= nullptr)
77 location_t locus
= expr
.get_locus ();
78 tree compiled_expr
= unit_expression (ctx
, expr
.get_locus ());
79 tree result_reference
= Backend::var_expression (result
, locus
);
82 = Backend::assignment_statement (result_reference
, compiled_expr
,
84 ctx
->add_statement (assignment
);
88 translated
= new_block
;
92 CompileConditionalBlocks::visit (HIR::IfExpr
&expr
)
94 fncontext fnctx
= ctx
->peek_fn ();
95 tree fndecl
= fnctx
.fndecl
;
97 = CompileExpr::Compile (expr
.get_if_condition ().get (), ctx
);
99 = CompileBlock::compile (expr
.get_if_block ().get (), ctx
, result
);
101 translated
= Backend::if_statement (fndecl
, condition_expr
, then_block
, NULL
,
106 CompileConditionalBlocks::visit (HIR::IfExprConseqElse
&expr
)
108 fncontext fnctx
= ctx
->peek_fn ();
109 tree fndecl
= fnctx
.fndecl
;
111 = CompileExpr::Compile (expr
.get_if_condition ().get (), ctx
);
113 = CompileBlock::compile (expr
.get_if_block ().get (), ctx
, result
);
116 std::vector
<Bvariable
*> locals
;
117 location_t start_location
= expr
.get_else_block ()->get_locus ();
118 location_t end_location
= expr
.get_else_block ()->get_locus (); // FIXME
119 tree enclosing_scope
= ctx
->peek_enclosing_scope ();
120 tree else_block
= Backend::block (fndecl
, enclosing_scope
, locals
,
121 start_location
, end_location
);
122 ctx
->push_block (else_block
);
125 = CompileExprWithBlock::compile (expr
.get_else_block ().get (), ctx
,
128 ctx
->add_statement (else_stmt_decl
);
132 translated
= Backend::if_statement (fndecl
, condition_expr
, then_block
,
133 else_block
, expr
.get_locus ());
136 } // namespace Compile