aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-stmt.cc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-08-17 12:12:36 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-08-17 13:01:13 +0100
commit73e79179486b21b13fd8dcc138f84398ca0306e4 (patch)
tree32a8727145460104e05c00f65b0c06f262c6179c /gcc/rust/backend/rust-compile-stmt.cc
parent4f039ff9f6f18d15e32ddb54e3a6124802c45b7f (diff)
downloadgcc-73e79179486b21b13fd8dcc138f84398ca0306e4.zip
gcc-73e79179486b21b13fd8dcc138f84398ca0306e4.tar.gz
gcc-73e79179486b21b13fd8dcc138f84398ca0306e4.tar.bz2
Refactor backend to use finegrained visitors
This also moves more code out of the headers to their associated impl files to improve compilation times and code navigation.
Diffstat (limited to 'gcc/rust/backend/rust-compile-stmt.cc')
-rw-r--r--gcc/rust/backend/rust-compile-stmt.cc115
1 files changed, 115 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-stmt.cc b/gcc/rust/backend/rust-compile-stmt.cc
new file mode 100644
index 0000000..bfb25f1
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-stmt.cc
@@ -0,0 +1,115 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-compile-stmt.h"
+#include "rust-compile-expr.h"
+
+namespace Rust {
+namespace Compile {
+
+CompileStmt::CompileStmt (Context *ctx)
+ : HIRCompileBase (ctx), translated (nullptr)
+{}
+
+tree
+CompileStmt::Compile (HIR::Stmt *stmt, Context *ctx)
+{
+ CompileStmt compiler (ctx);
+ stmt->accept_vis (compiler);
+ return compiler.translated;
+}
+
+void
+CompileStmt::visit (HIR::ExprStmtWithBlock &stmt)
+{
+ translated = CompileExpr::Compile (stmt.get_expr (), ctx);
+}
+
+void
+CompileStmt::visit (HIR::ExprStmtWithoutBlock &stmt)
+{
+ translated = CompileExpr::Compile (stmt.get_expr (), ctx);
+}
+
+void
+CompileStmt::visit (HIR::LetStmt &stmt)
+{
+ // nothing to do
+ if (!stmt.has_init_expr ())
+ return;
+
+ const HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
+ HirId stmt_id = stmt_pattern.get_pattern_mappings ().get_hirid ();
+
+ TyTy::BaseType *ty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (stmt_id, &ty))
+ {
+ // FIXME this should be an assertion instead
+ rust_fatal_error (stmt.get_locus (),
+ "failed to lookup variable declaration type");
+ return;
+ }
+
+ Bvariable *var = nullptr;
+ if (!ctx->lookup_var_decl (stmt_id, &var))
+ {
+ // FIXME this should be an assertion instead and use error mark node
+ rust_fatal_error (stmt.get_locus (),
+ "failed to lookup compiled variable declaration");
+ return;
+ }
+
+ tree init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
+ // FIXME use error_mark_node, check that CompileExpr returns error_mark_node
+ // on failure and make this an assertion
+ if (init == nullptr)
+ return;
+
+ TyTy::BaseType *actual = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ stmt.get_init_expr ()->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+ tree stmt_type = TyTyResolveCompile::compile (ctx, ty);
+
+ Location lvalue_locus = stmt.get_pattern ()->get_locus ();
+ Location rvalue_locus = stmt.get_init_expr ()->get_locus ();
+ TyTy::BaseType *expected = ty;
+ init = coercion_site (stmt.get_mappings ().get_hirid (), init, actual,
+ expected, lvalue_locus, rvalue_locus);
+
+ auto fnctx = ctx->peek_fn ();
+ if (ty->is_unit ())
+ {
+ ctx->add_statement (init);
+
+ auto unit_type_init_expr
+ = ctx->get_backend ()->constructor_expression (stmt_type, false, {}, -1,
+ rvalue_locus);
+ auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var,
+ unit_type_init_expr);
+ ctx->add_statement (s);
+ }
+ else
+ {
+ auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var, init);
+ ctx->add_statement (s);
+ }
+}
+
+} // namespace Compile
+} // namespace Rust