Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / rust / backend / rust-compile-block.cc
blob3942571ae7de4e5bc4da756c50435bb3726a9255
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 start_location = expr.get_locus ();
44 Location end_location = expr.get_end_locus ();
45 auto body_mappings = expr.get_mappings ();
47 Resolver::Rib *rib = nullptr;
48 if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), &rib))
50 rust_fatal_error (expr.get_locus (), "failed to setup locals per block");
51 return;
54 std::vector<Bvariable *> locals
55 = compile_locals_for_block (ctx, *rib, fndecl);
57 tree enclosing_scope = ctx->peek_enclosing_scope ();
58 tree new_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
59 start_location, end_location);
60 ctx->push_block (new_block);
62 for (auto &s : expr.get_statements ())
64 auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
65 if (compiled_expr != nullptr)
67 tree s = convert_to_void (compiled_expr, ICV_STATEMENT);
68 ctx->add_statement (s);
72 if (expr.has_expr ())
74 // the previous passes will ensure this is a valid return or
75 // a valid trailing expression
76 tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
77 if (compiled_expr != nullptr)
79 if (result == nullptr)
81 ctx->add_statement (compiled_expr);
83 else
85 tree result_reference = ctx->get_backend ()->var_expression (
86 result, expr.get_final_expr ()->get_locus ());
88 tree assignment
89 = ctx->get_backend ()->assignment_statement (result_reference,
90 compiled_expr,
91 expr.get_locus ());
92 ctx->add_statement (assignment);
97 ctx->pop_block ();
98 translated = new_block;
101 void
102 CompileConditionalBlocks::visit (HIR::IfExpr &expr)
104 fncontext fnctx = ctx->peek_fn ();
105 tree fndecl = fnctx.fndecl;
106 tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
107 tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
109 translated
110 = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
111 NULL, expr.get_locus ());
114 void
115 CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
117 fncontext fnctx = ctx->peek_fn ();
118 tree fndecl = fnctx.fndecl;
119 tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
120 tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
121 tree else_block = CompileBlock::compile (expr.get_else_block (), ctx, result);
123 translated
124 = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
125 else_block, expr.get_locus ());
128 void
129 CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr)
131 fncontext fnctx = ctx->peek_fn ();
132 tree fndecl = fnctx.fndecl;
133 tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
134 tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
136 // else block
137 std::vector<Bvariable *> locals;
138 Location start_location = expr.get_conseq_if_expr ()->get_locus ();
139 Location end_location = expr.get_conseq_if_expr ()->get_locus (); // FIXME
140 tree enclosing_scope = ctx->peek_enclosing_scope ();
141 tree else_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
142 start_location, end_location);
143 ctx->push_block (else_block);
145 tree else_stmt_decl
146 = CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx,
147 result);
148 ctx->add_statement (else_stmt_decl);
150 ctx->pop_block ();
152 translated
153 = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
154 else_block, expr.get_locus ());
157 } // namespace Compile
158 } // namespace Rust