Fortran: fix ALLOCATE with SOURCE of deferred character length [PR114019]
[official-gcc.git] / gcc / rust / backend / rust-compile-block.cc
blob10a70999773510a988deb6a11477b20039322445
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
8 // version.
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.
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"
23 namespace Rust {
24 namespace Compile {
26 CompileBlock::CompileBlock (Context *ctx, Bvariable *result)
27 : HIRCompileBase (ctx), translated (nullptr), result (result)
30 tree
31 CompileBlock::compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
33 CompileBlock compiler (ctx, result);
34 compiler.visit (*expr);
35 return compiler.translated;
38 void
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);
61 if (expr.has_expr ())
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);
69 tree assignment
70 = Backend::assignment_statement (result_reference, compiled_expr,
71 expr.get_locus ());
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);
81 tree assignment
82 = Backend::assignment_statement (result_reference, compiled_expr,
83 expr.get_locus ());
84 ctx->add_statement (assignment);
87 ctx->pop_block ();
88 translated = new_block;
91 void
92 CompileConditionalBlocks::visit (HIR::IfExpr &expr)
94 fncontext fnctx = ctx->peek_fn ();
95 tree fndecl = fnctx.fndecl;
96 tree condition_expr
97 = CompileExpr::Compile (expr.get_if_condition ().get (), ctx);
98 tree then_block
99 = CompileBlock::compile (expr.get_if_block ().get (), ctx, result);
101 translated = Backend::if_statement (fndecl, condition_expr, then_block, NULL,
102 expr.get_locus ());
105 void
106 CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
108 fncontext fnctx = ctx->peek_fn ();
109 tree fndecl = fnctx.fndecl;
110 tree condition_expr
111 = CompileExpr::Compile (expr.get_if_condition ().get (), ctx);
112 tree then_block
113 = CompileBlock::compile (expr.get_if_block ().get (), ctx, result);
115 // else block
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);
124 tree else_stmt_decl
125 = CompileExprWithBlock::compile (expr.get_else_block ().get (), ctx,
126 result);
128 ctx->add_statement (else_stmt_decl);
130 ctx->pop_block ();
132 translated = Backend::if_statement (fndecl, condition_expr, then_block,
133 else_block, expr.get_locus ());
136 } // namespace Compile
137 } // namespace Rust