aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/rust/Make-lang.in3
-rw-r--r--gcc/rust/backend/rust-compile-base.cc3
-rw-r--r--gcc/rust/backend/rust-compile-block.cc158
-rw-r--r--gcc/rust/backend/rust-compile-block.h71
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc746
-rw-r--r--gcc/rust/backend/rust-compile-expr.h769
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.cc59
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h57
-rw-r--r--gcc/rust/backend/rust-compile-item.h2
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc3
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc1
-rw-r--r--gcc/rust/backend/rust-compile-stmt.cc115
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h88
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.cc81
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.h75
-rw-r--r--gcc/rust/backend/rust-compile-type.h2
-rw-r--r--gcc/rust/backend/rust-compile.cc161
17 files changed, 1222 insertions, 1172 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 23dad26..49be3a1 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -137,8 +137,11 @@ GRS_OBJS = \
rust/rust-optional-test.o \
rust/rust-compile-item.o \
rust/rust-compile-implitem.o \
+ rust/rust-compile-stmt.o \
rust/rust-compile-expr.o \
rust/rust-compile-type.o \
+ rust/rust-compile-block.o \
+ rust/rust-compile-struct-field-expr.o \
rust/rust-constexpr.o \
rust/rust-compile-base.o \
rust/rust-tree.o \
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index a640a48..2b5c850 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -20,9 +20,10 @@
#include "rust-abi.h"
#include "rust-compile-item.h"
#include "rust-compile-stmt.h"
+#include "rust-compile-expr.h"
#include "rust-compile-fnparam.h"
#include "rust-compile-var-decl.h"
-
+#include "rust-constexpr.h"
#include "rust-diagnostics.h"
#include "rust-expr.h" // for AST::AttrInputLiteral
#include "rust-macro.h" // for AST::MetaNameValueStr
diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc
new file mode 100644
index 0000000..99674e2
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -0,0 +1,158 @@
+// 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-block.h"
+#include "rust-compile-stmt.h"
+#include "rust-compile-expr.h"
+
+namespace Rust {
+namespace Compile {
+
+CompileBlock::CompileBlock (Context *ctx, Bvariable *result)
+ : HIRCompileBase (ctx), translated (nullptr), result (result)
+{}
+
+tree
+CompileBlock::compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
+{
+ CompileBlock compiler (ctx, result);
+ compiler.visit (*expr);
+ return compiler.translated;
+}
+
+void
+CompileBlock::visit (HIR::BlockExpr &expr)
+{
+ fncontext fnctx = ctx->peek_fn ();
+ tree fndecl = fnctx.fndecl;
+ Location start_location = expr.get_locus ();
+ Location end_location = expr.get_end_locus ();
+ auto body_mappings = expr.get_mappings ();
+
+ Resolver::Rib *rib = nullptr;
+ if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), &rib))
+ {
+ rust_fatal_error (expr.get_locus (), "failed to setup locals per block");
+ return;
+ }
+
+ std::vector<Bvariable *> locals
+ = compile_locals_for_block (ctx, *rib, fndecl);
+
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree new_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+ start_location, end_location);
+ ctx->push_block (new_block);
+
+ for (auto &s : expr.get_statements ())
+ {
+ auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
+ if (compiled_expr != nullptr)
+ {
+ tree s = convert_to_void (compiled_expr, ICV_STATEMENT);
+ ctx->add_statement (s);
+ }
+ }
+
+ if (expr.has_expr ())
+ {
+ // the previous passes will ensure this is a valid return or
+ // a valid trailing expression
+ tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
+ if (compiled_expr != nullptr)
+ {
+ if (result == nullptr)
+ {
+ ctx->add_statement (compiled_expr);
+ }
+ else
+ {
+ tree result_reference = ctx->get_backend ()->var_expression (
+ result, expr.get_final_expr ()->get_locus ());
+
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (result_reference,
+ compiled_expr,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
+ }
+ }
+
+ ctx->pop_block ();
+ translated = new_block;
+}
+
+void
+CompileConditionalBlocks::visit (HIR::IfExpr &expr)
+{
+ fncontext fnctx = ctx->peek_fn ();
+ tree fndecl = fnctx.fndecl;
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
+
+ translated
+ = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
+ NULL, expr.get_locus ());
+}
+
+void
+CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
+{
+ fncontext fnctx = ctx->peek_fn ();
+ tree fndecl = fnctx.fndecl;
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
+ tree else_block = CompileBlock::compile (expr.get_else_block (), ctx, result);
+
+ translated
+ = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
+ else_block, expr.get_locus ());
+}
+
+void
+CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr)
+{
+ fncontext fnctx = ctx->peek_fn ();
+ tree fndecl = fnctx.fndecl;
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
+
+ // else block
+ std::vector<Bvariable *> locals;
+ Location start_location = expr.get_conseq_if_expr ()->get_locus ();
+ Location end_location = expr.get_conseq_if_expr ()->get_locus (); // FIXME
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree else_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+ start_location, end_location);
+ ctx->push_block (else_block);
+
+ tree else_stmt_decl
+ = CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx,
+ result);
+ ctx->add_statement (else_stmt_decl);
+
+ ctx->pop_block ();
+
+ translated
+ = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
+ else_block, expr.get_locus ());
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index e3c7399..cdd17f1 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -24,77 +24,16 @@
namespace Rust {
namespace Compile {
-class CompileBlock : public HIRCompileBase, public HIR::HIRExpressionVisitor
+class CompileBlock : private HIRCompileBase
{
public:
- static tree compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
- {
- CompileBlock compiler (ctx, result);
- expr->accept_vis (compiler);
- return compiler.translated;
- }
+ static tree compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result);
- void visit (HIR::BlockExpr &expr) override;
-
- // Empty visit for unused Expression HIR nodes.
- void visit (HIR::PathInExpression &) override {}
- void visit (HIR::QualifiedPathInExpression &) override {}
- void visit (HIR::ClosureExprInner &) override {}
- void visit (HIR::ClosureExprInnerTyped &) override {}
- void visit (HIR::StructExprFieldIdentifier &) override {}
- void visit (HIR::StructExprFieldIdentifierValue &) override {}
- void visit (HIR::StructExprFieldIndexValue &) override {}
- void visit (HIR::StructExprStruct &) override {}
- void visit (HIR::StructExprStructFields &) override {}
- void visit (HIR::LiteralExpr &) override {}
- void visit (HIR::BorrowExpr &) override {}
- void visit (HIR::DereferenceExpr &) override {}
- void visit (HIR::ErrorPropagationExpr &) override {}
- void visit (HIR::NegationExpr &) override {}
- void visit (HIR::ArithmeticOrLogicalExpr &) override {}
- void visit (HIR::ComparisonExpr &) override {}
- void visit (HIR::LazyBooleanExpr &) override {}
- void visit (HIR::TypeCastExpr &) override {}
- void visit (HIR::AssignmentExpr &) override {}
- void visit (HIR::CompoundAssignmentExpr &) override {}
- void visit (HIR::GroupedExpr &) override {}
- void visit (HIR::ArrayExpr &) override {}
- void visit (HIR::ArrayIndexExpr &) override {}
- void visit (HIR::TupleExpr &) override {}
- void visit (HIR::TupleIndexExpr &) override {}
- void visit (HIR::CallExpr &) override {}
- void visit (HIR::MethodCallExpr &) override {}
- void visit (HIR::FieldAccessExpr &) override {}
- void visit (HIR::ContinueExpr &) override {}
- void visit (HIR::BreakExpr &) override {}
- void visit (HIR::RangeFromToExpr &) override {}
- void visit (HIR::RangeFromExpr &) override {}
- void visit (HIR::RangeToExpr &) override {}
- void visit (HIR::RangeFullExpr &) override {}
- void visit (HIR::RangeFromToInclExpr &) override {}
- void visit (HIR::RangeToInclExpr &) override {}
- void visit (HIR::ReturnExpr &) override {}
- void visit (HIR::UnsafeBlockExpr &) override {}
- void visit (HIR::LoopExpr &) override {}
- void visit (HIR::WhileLoopExpr &) override {}
- void visit (HIR::WhileLetLoopExpr &) override {}
- void visit (HIR::ForLoopExpr &) override {}
- void visit (HIR::IfExpr &) override {}
- void visit (HIR::IfExprConseqElse &) override {}
- void visit (HIR::IfExprConseqIf &) override {}
- void visit (HIR::IfExprConseqIfLet &) override {}
- void visit (HIR::IfLetExpr &) override {}
- void visit (HIR::IfLetExprConseqElse &) override {}
- void visit (HIR::IfLetExprConseqIf &) override {}
- void visit (HIR::IfLetExprConseqIfLet &) override {}
- void visit (HIR::MatchExpr &) override {}
- void visit (HIR::AwaitExpr &) override {}
- void visit (HIR::AsyncBlockExpr &) override {}
+protected:
+ void visit (HIR::BlockExpr &expr);
private:
- CompileBlock (Context *ctx, Bvariable *result)
- : HIRCompileBase (ctx), translated (nullptr), result (result)
- {}
+ CompileBlock (Context *ctx, Bvariable *result);
tree translated;
Bvariable *result;
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index bfaa7fc..9a8b779 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -16,15 +16,15 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include "rust-compile.h"
-#include "rust-compile-item.h"
-#include "rust-compile-implitem.h"
#include "rust-compile-expr.h"
#include "rust-compile-struct-field-expr.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
#include "rust-hir-type-bounds.h"
#include "rust-compile-pattern.h"
+#include "rust-compile-resolve-path.h"
+#include "rust-compile-block.h"
+#include "rust-compile-implitem.h"
#include "rust-constexpr.h"
#include "fold-const.h"
@@ -35,6 +35,97 @@
namespace Rust {
namespace Compile {
+CompileExpr::CompileExpr (Context *ctx)
+ : HIRCompileBase (ctx), translated (error_mark_node)
+{}
+
+tree
+CompileExpr::Compile (HIR::Expr *expr, Context *ctx)
+{
+ CompileExpr compiler (ctx);
+ expr->accept_vis (compiler);
+ return compiler.translated;
+}
+
+void
+CompileExpr::visit (HIR::TupleIndexExpr &expr)
+{
+ HIR::Expr *tuple_expr = expr.get_tuple_expr ().get ();
+ TupleIndex index = expr.get_tuple_index ();
+
+ tree receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
+
+ TyTy::BaseType *tuple_expr_ty = nullptr;
+ bool ok
+ = ctx->get_tyctx ()->lookup_type (tuple_expr->get_mappings ().get_hirid (),
+ &tuple_expr_ty);
+ rust_assert (ok);
+
+ // do we need to add an indirect reference
+ if (tuple_expr_ty->get_kind () == TyTy::TypeKind::REF)
+ {
+ tree indirect = indirect_expression (receiver_ref, expr.get_locus ());
+ receiver_ref = indirect;
+ }
+
+ translated
+ = ctx->get_backend ()->struct_field_expression (receiver_ref, index,
+ expr.get_locus ());
+}
+
+void
+CompileExpr::visit (HIR::TupleExpr &expr)
+{
+ if (expr.is_unit ())
+ {
+ translated = ctx->get_backend ()->unit_expression ();
+ return;
+ }
+
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ rust_fatal_error (expr.get_locus (),
+ "did not resolve type for this TupleExpr");
+ return;
+ }
+
+ tree tuple_type = TyTyResolveCompile::compile (ctx, tyty);
+ rust_assert (tuple_type != nullptr);
+
+ // this assumes all fields are in order from type resolution
+ std::vector<tree> vals;
+ for (auto &elem : expr.get_tuple_elems ())
+ {
+ auto e = CompileExpr::Compile (elem.get (), ctx);
+ vals.push_back (e);
+ }
+
+ translated
+ = ctx->get_backend ()->constructor_expression (tuple_type, false, vals, -1,
+ expr.get_locus ());
+}
+
+void
+CompileExpr::visit (HIR::ReturnExpr &expr)
+{
+ auto fncontext = ctx->peek_fn ();
+
+ std::vector<tree> retstmts;
+ if (expr.has_return_expr ())
+ {
+ tree compiled_expr = CompileExpr::Compile (expr.return_expr.get (), ctx);
+ rust_assert (compiled_expr != nullptr);
+
+ retstmts.push_back (compiled_expr);
+ }
+
+ auto s = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts,
+ expr.get_locus ());
+ ctx->add_statement (s);
+}
+
void
CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
{
@@ -120,6 +211,585 @@ CompileExpr::visit (HIR::NegationExpr &expr)
}
void
+CompileExpr::visit (HIR::ComparisonExpr &expr)
+{
+ auto op = expr.get_expr_type ();
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+ auto location = expr.get_locus ();
+
+ translated
+ = ctx->get_backend ()->comparison_expression (op, lhs, rhs, location);
+}
+
+void
+CompileExpr::visit (HIR::LazyBooleanExpr &expr)
+{
+ auto op = expr.get_expr_type ();
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+ auto location = expr.get_locus ();
+
+ translated
+ = ctx->get_backend ()->lazy_boolean_expression (op, lhs, rhs, location);
+}
+
+void
+CompileExpr::visit (HIR::TypeCastExpr &expr)
+{
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ translated = error_mark_node;
+ return;
+ }
+
+ auto type_to_cast_to = TyTyResolveCompile::compile (ctx, tyty);
+ auto casted_expr = CompileExpr::Compile (expr.get_casted_expr ().get (), ctx);
+ translated
+ = type_cast_expression (type_to_cast_to, casted_expr, expr.get_locus ());
+}
+
+void
+CompileExpr::visit (HIR::IfExpr &expr)
+{
+ auto stmt = CompileConditionalBlocks::compile (&expr, ctx, nullptr);
+ ctx->add_statement (stmt);
+}
+
+void
+CompileExpr::visit (HIR::IfExprConseqElse &expr)
+{
+ TyTy::BaseType *if_type = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &if_type))
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup type of IfExprConseqElse");
+ return;
+ }
+
+ Bvariable *tmp = NULL;
+ bool needs_temp = !if_type->is_unit ();
+ if (needs_temp)
+ {
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, if_type);
+
+ bool is_address_taken = false;
+ tree ret_var_stmt = nullptr;
+ tmp = ctx->get_backend ()->temporary_variable (
+ fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
+ expr.get_locus (), &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+ }
+
+ auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp);
+ ctx->add_statement (stmt);
+
+ if (tmp != NULL)
+ {
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
+ }
+}
+
+void
+CompileExpr::visit (HIR::IfExprConseqIf &expr)
+{
+ TyTy::BaseType *if_type = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &if_type))
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup type of IfExprConseqElse");
+ return;
+ }
+
+ Bvariable *tmp = NULL;
+ bool needs_temp = !if_type->is_unit ();
+ if (needs_temp)
+ {
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, if_type);
+
+ bool is_address_taken = false;
+ tree ret_var_stmt = nullptr;
+ tmp = ctx->get_backend ()->temporary_variable (
+ fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
+ expr.get_locus (), &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+ }
+
+ auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp);
+ ctx->add_statement (stmt);
+
+ if (tmp != NULL)
+ {
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
+ }
+}
+
+void
+CompileExpr::visit (HIR::BlockExpr &expr)
+{
+ TyTy::BaseType *block_tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &block_tyty))
+ {
+ rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
+ return;
+ }
+
+ Bvariable *tmp = NULL;
+ bool needs_temp = !block_tyty->is_unit ();
+ if (needs_temp)
+ {
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
+
+ bool is_address_taken = false;
+ tree ret_var_stmt = nullptr;
+ tmp = ctx->get_backend ()->temporary_variable (
+ fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
+ expr.get_locus (), &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+ }
+
+ auto block_stmt = CompileBlock::compile (&expr, ctx, tmp);
+ rust_assert (TREE_CODE (block_stmt) == BIND_EXPR);
+ ctx->add_statement (block_stmt);
+
+ if (tmp != NULL)
+ {
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
+ }
+}
+
+void
+CompileExpr::visit (HIR::UnsafeBlockExpr &expr)
+{
+ expr.get_block_expr ()->accept_vis (*this);
+}
+
+void
+CompileExpr::visit (HIR::StructExprStruct &struct_expr)
+{
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (struct_expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ rust_error_at (struct_expr.get_locus (), "unknown type");
+ return;
+ }
+
+ rust_assert (tyty->is_unit ());
+ translated = ctx->get_backend ()->unit_expression ();
+}
+
+void
+CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
+{
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (struct_expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ rust_error_at (struct_expr.get_locus (), "unknown type");
+ return;
+ }
+
+ // it must be an ADT
+ rust_assert (tyty->get_kind () == TyTy::TypeKind::ADT);
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyty);
+
+ // what variant is it?
+ int union_disriminator = struct_expr.union_index;
+ TyTy::VariantDef *variant = nullptr;
+ if (!adt->is_enum ())
+ {
+ rust_assert (adt->number_of_variants () == 1);
+ variant = adt->get_variants ().at (0);
+ }
+ else
+ {
+ HirId variant_id;
+ bool ok = ctx->get_tyctx ()->lookup_variant_definition (
+ struct_expr.get_struct_name ().get_mappings ().get_hirid (),
+ &variant_id);
+ rust_assert (ok);
+
+ ok
+ = adt->lookup_variant_by_id (variant_id, &variant, &union_disriminator);
+ rust_assert (ok);
+ }
+
+ // compile it
+ tree compiled_adt_type = TyTyResolveCompile::compile (ctx, tyty);
+
+ std::vector<tree> arguments;
+ if (adt->is_union ())
+ {
+ rust_assert (struct_expr.get_fields ().size () == 1);
+
+ // assignments are coercion sites so lets convert the rvalue if
+ // necessary
+ auto respective_field = variant->get_field_at_index (union_disriminator);
+ auto expected = respective_field->get_field_type ();
+
+ // process arguments
+ auto &argument = struct_expr.get_fields ().at (0);
+ auto lvalue_locus
+ = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
+ auto rvalue_locus = argument->get_locus ();
+ auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+
+ TyTy::BaseType *actual = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ argument->get_mappings ().get_hirid (), &actual);
+
+ if (ok)
+ {
+ rvalue
+ = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
+ actual, expected, lvalue_locus, rvalue_locus);
+ }
+
+ // add it to the list
+ arguments.push_back (rvalue);
+ }
+ else
+ {
+ // this assumes all fields are in order from type resolution and if a
+ // base struct was specified those fields are filed via accesors
+ for (size_t i = 0; i < struct_expr.get_fields ().size (); i++)
+ {
+ // assignments are coercion sites so lets convert the rvalue if
+ // necessary
+ auto respective_field = variant->get_field_at_index (i);
+ auto expected = respective_field->get_field_type ();
+
+ // process arguments
+ auto &argument = struct_expr.get_fields ().at (i);
+ auto lvalue_locus
+ = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
+ auto rvalue_locus = argument->get_locus ();
+ auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+
+ TyTy::BaseType *actual = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ argument->get_mappings ().get_hirid (), &actual);
+
+ // coerce it if required/possible see
+ // compile/torture/struct_base_init_1.rs
+ if (ok)
+ {
+ rvalue
+ = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
+ actual, expected, lvalue_locus, rvalue_locus);
+ }
+
+ // add it to the list
+ arguments.push_back (rvalue);
+ }
+ }
+
+ // the constructor depends on whether this is actually an enum or not if
+ // its an enum we need to setup the discriminator
+ std::vector<tree> ctor_arguments;
+ if (adt->is_enum ())
+ {
+ HIR::Expr *discrim_expr = variant->get_discriminant ();
+ tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+ tree folded_discrim_expr = fold_expr (discrim_expr_node);
+ tree qualifier = folded_discrim_expr;
+
+ ctor_arguments.push_back (qualifier);
+ }
+ for (auto &arg : arguments)
+ ctor_arguments.push_back (arg);
+
+ translated = ctx->get_backend ()->constructor_expression (
+ compiled_adt_type, adt->is_enum (), ctor_arguments, union_disriminator,
+ struct_expr.get_locus ());
+}
+
+void
+CompileExpr::visit (HIR::GroupedExpr &expr)
+{
+ translated = CompileExpr::Compile (expr.get_expr_in_parens ().get (), ctx);
+}
+
+void
+CompileExpr::visit (HIR::FieldAccessExpr &expr)
+{
+ HIR::Expr *receiver_expr = expr.get_receiver_expr ().get ();
+ tree receiver_ref = CompileExpr::Compile (receiver_expr, ctx);
+
+ // resolve the receiver back to ADT type
+ TyTy::BaseType *receiver = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
+ {
+ rust_error_at (expr.get_receiver_expr ()->get_locus (),
+ "unresolved type for receiver");
+ return;
+ }
+
+ size_t field_index = 0;
+ if (receiver->get_kind () == TyTy::TypeKind::ADT)
+ {
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver);
+ rust_assert (!adt->is_enum ());
+ rust_assert (adt->number_of_variants () == 1);
+
+ TyTy::VariantDef *variant = adt->get_variants ().at (0);
+ bool ok
+ = variant->lookup_field (expr.get_field_name (), nullptr, &field_index);
+ rust_assert (ok);
+ }
+ else if (receiver->get_kind () == TyTy::TypeKind::REF)
+ {
+ TyTy::ReferenceType *r = static_cast<TyTy::ReferenceType *> (receiver);
+ TyTy::BaseType *b = r->get_base ();
+ rust_assert (b->get_kind () == TyTy::TypeKind::ADT);
+
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (b);
+ rust_assert (!adt->is_enum ());
+ rust_assert (adt->number_of_variants () == 1);
+
+ TyTy::VariantDef *variant = adt->get_variants ().at (0);
+ bool ok
+ = variant->lookup_field (expr.get_field_name (), nullptr, &field_index);
+ rust_assert (ok);
+
+ tree indirect = indirect_expression (receiver_ref, expr.get_locus ());
+ receiver_ref = indirect;
+ }
+
+ translated
+ = ctx->get_backend ()->struct_field_expression (receiver_ref, field_index,
+ expr.get_locus ());
+}
+
+void
+CompileExpr::visit (HIR::QualifiedPathInExpression &expr)
+{
+ translated = ResolvePathRef::Compile (expr, ctx);
+}
+
+void
+CompileExpr::visit (HIR::PathInExpression &expr)
+{
+ translated = ResolvePathRef::Compile (expr, ctx);
+}
+
+void
+CompileExpr::visit (HIR::LoopExpr &expr)
+{
+ TyTy::BaseType *block_tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &block_tyty))
+ {
+ rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
+ return;
+ }
+
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
+
+ bool is_address_taken = false;
+ tree ret_var_stmt = NULL_TREE;
+ Bvariable *tmp = ctx->get_backend ()->temporary_variable (
+ fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
+ expr.get_locus (), &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+ ctx->push_loop_context (tmp);
+
+ if (expr.has_loop_label ())
+ {
+ HIR::LoopLabel &loop_label = expr.get_loop_label ();
+ tree label
+ = ctx->get_backend ()->label (fnctx.fndecl,
+ loop_label.get_lifetime ().get_name (),
+ loop_label.get_locus ());
+ tree label_decl = ctx->get_backend ()->label_definition_statement (label);
+ ctx->add_statement (label_decl);
+ ctx->insert_label_decl (
+ loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
+ }
+
+ tree loop_begin_label
+ = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
+ tree loop_begin_label_decl
+ = ctx->get_backend ()->label_definition_statement (loop_begin_label);
+ ctx->add_statement (loop_begin_label_decl);
+ ctx->push_loop_begin_label (loop_begin_label);
+
+ tree code_block
+ = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
+ tree loop_expr
+ = ctx->get_backend ()->loop_expression (code_block, expr.get_locus ());
+ ctx->add_statement (loop_expr);
+
+ ctx->pop_loop_context ();
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
+
+ ctx->pop_loop_begin_label ();
+}
+
+void
+CompileExpr::visit (HIR::WhileLoopExpr &expr)
+{
+ fncontext fnctx = ctx->peek_fn ();
+ if (expr.has_loop_label ())
+ {
+ HIR::LoopLabel &loop_label = expr.get_loop_label ();
+ tree label
+ = ctx->get_backend ()->label (fnctx.fndecl,
+ loop_label.get_lifetime ().get_name (),
+ loop_label.get_locus ());
+ tree label_decl = ctx->get_backend ()->label_definition_statement (label);
+ ctx->add_statement (label_decl);
+ ctx->insert_label_decl (
+ loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
+ }
+
+ std::vector<Bvariable *> locals;
+ Location start_location = expr.get_loop_block ()->get_locus ();
+ Location end_location = expr.get_loop_block ()->get_locus (); // FIXME
+
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree loop_block
+ = ctx->get_backend ()->block (fnctx.fndecl, enclosing_scope, locals,
+ start_location, end_location);
+ ctx->push_block (loop_block);
+
+ tree loop_begin_label
+ = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
+ tree loop_begin_label_decl
+ = ctx->get_backend ()->label_definition_statement (loop_begin_label);
+ ctx->add_statement (loop_begin_label_decl);
+ ctx->push_loop_begin_label (loop_begin_label);
+
+ tree condition
+ = CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
+ tree exit_expr
+ = ctx->get_backend ()->exit_expression (condition, expr.get_locus ());
+ ctx->add_statement (exit_expr);
+
+ tree code_block_stmt
+ = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
+ rust_assert (TREE_CODE (code_block_stmt) == BIND_EXPR);
+ ctx->add_statement (code_block_stmt);
+
+ ctx->pop_loop_begin_label ();
+ ctx->pop_block ();
+
+ tree loop_expr
+ = ctx->get_backend ()->loop_expression (loop_block, expr.get_locus ());
+ ctx->add_statement (loop_expr);
+}
+
+void
+CompileExpr::visit (HIR::BreakExpr &expr)
+{
+ if (expr.has_break_expr ())
+ {
+ tree compiled_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+
+ Bvariable *loop_result_holder = ctx->peek_loop_context ();
+ tree result_reference
+ = ctx->get_backend ()->var_expression (loop_result_holder,
+ expr.get_expr ()->get_locus ());
+
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (result_reference,
+ compiled_expr,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
+
+ if (expr.has_label ())
+ {
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ if (!ctx->get_resolver ()->lookup_resolved_label (
+ expr.get_label ().get_mappings ().get_nodeid (), &resolved_node_id))
+ {
+ rust_error_at (
+ expr.get_label ().get_locus (),
+ "failed to resolve compiled label for label %s",
+ expr.get_label ().get_mappings ().as_string ().c_str ());
+ return;
+ }
+
+ HirId ref = UNKNOWN_HIRID;
+ if (!ctx->get_mappings ()->lookup_node_to_hir (resolved_node_id, &ref))
+ {
+ rust_fatal_error (expr.get_locus (), "reverse lookup label failure");
+ return;
+ }
+
+ tree label = NULL_TREE;
+ if (!ctx->lookup_label_decl (ref, &label))
+ {
+ rust_error_at (expr.get_label ().get_locus (),
+ "failed to lookup compiled label");
+ return;
+ }
+
+ tree goto_label
+ = ctx->get_backend ()->goto_statement (label, expr.get_locus ());
+ ctx->add_statement (goto_label);
+ }
+ else
+ {
+ tree exit_expr = ctx->get_backend ()->exit_expression (
+ ctx->get_backend ()->boolean_constant_expression (true),
+ expr.get_locus ());
+ ctx->add_statement (exit_expr);
+ }
+}
+
+void
+CompileExpr::visit (HIR::ContinueExpr &expr)
+{
+ tree label = ctx->peek_loop_begin_label ();
+ if (expr.has_label ())
+ {
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ if (!ctx->get_resolver ()->lookup_resolved_label (
+ expr.get_label ().get_mappings ().get_nodeid (), &resolved_node_id))
+ {
+ rust_error_at (
+ expr.get_label ().get_locus (),
+ "failed to resolve compiled label for label %s",
+ expr.get_label ().get_mappings ().as_string ().c_str ());
+ return;
+ }
+
+ HirId ref = UNKNOWN_HIRID;
+ if (!ctx->get_mappings ()->lookup_node_to_hir (resolved_node_id, &ref))
+ {
+ rust_fatal_error (expr.get_locus (), "reverse lookup label failure");
+ return;
+ }
+
+ if (!ctx->lookup_label_decl (ref, &label))
+ {
+ rust_error_at (expr.get_label ().get_locus (),
+ "failed to lookup compiled label");
+ return;
+ }
+ }
+
+ translated = ctx->get_backend ()->goto_statement (label, expr.get_locus ());
+}
+
+void
CompileExpr::visit (HIR::BorrowExpr &expr)
{
tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
@@ -177,6 +847,76 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
translated = indirect_expression (main_expr, expr.get_locus ());
}
+void
+CompileExpr::visit (HIR::LiteralExpr &expr)
+{
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &tyty))
+ return;
+
+ switch (expr.get_lit_type ())
+ {
+ case HIR::Literal::BOOL:
+ translated = compile_bool_literal (expr, tyty);
+ return;
+
+ case HIR::Literal::INT:
+ translated = compile_integer_literal (expr, tyty);
+ return;
+
+ case HIR::Literal::FLOAT:
+ translated = compile_float_literal (expr, tyty);
+ return;
+
+ case HIR::Literal::CHAR:
+ translated = compile_char_literal (expr, tyty);
+ return;
+
+ case HIR::Literal::BYTE:
+ translated = compile_byte_literal (expr, tyty);
+ return;
+
+ case HIR::Literal::STRING:
+ translated = compile_string_literal (expr, tyty);
+ return;
+
+ case HIR::Literal::BYTE_STRING:
+ translated = compile_byte_string_literal (expr, tyty);
+ return;
+ }
+}
+
+void
+CompileExpr::visit (HIR::AssignmentExpr &expr)
+{
+ auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ // assignments are coercion sites so lets convert the rvalue if necessary
+ TyTy::BaseType *expected = nullptr;
+ TyTy::BaseType *actual = nullptr;
+
+ bool ok;
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_lhs ()->get_mappings ().get_hirid (), &expected);
+ rust_assert (ok);
+
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ rvalue = coercion_site (expr.get_mappings ().get_hirid (), rvalue, actual,
+ expected, expr.get_lhs ()->get_locus (),
+ expr.get_rhs ()->get_locus ());
+
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (lvalue, rvalue,
+ expr.get_locus ());
+
+ ctx->add_statement (assignment);
+}
+
// Helper for sort_tuple_patterns.
// Determine whether Patterns a and b are really the same pattern.
// FIXME: This is a nasty hack to avoid properly implementing a comparison
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 69f9492..4c1f95a 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -20,767 +20,52 @@
#define RUST_COMPILE_EXPR
#include "rust-compile-base.h"
-#include "rust-compile-resolve-path.h"
-#include "rust-compile-block.h"
-#include "rust-compile-struct-field-expr.h"
-#include "rust-constexpr.h"
namespace Rust {
namespace Compile {
-class CompileExpr : public HIRCompileBase, public HIR::HIRExpressionVisitor
+class CompileExpr : private HIRCompileBase, protected HIR::HIRExpressionVisitor
{
public:
- static tree Compile (HIR::Expr *expr, Context *ctx)
- {
- CompileExpr compiler (ctx);
- expr->accept_vis (compiler);
- return compiler.translated;
- }
-
- void visit (HIR::TupleIndexExpr &expr) override
- {
- HIR::Expr *tuple_expr = expr.get_tuple_expr ().get ();
- TupleIndex index = expr.get_tuple_index ();
-
- tree receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
-
- TyTy::BaseType *tuple_expr_ty = nullptr;
- bool ok = ctx->get_tyctx ()->lookup_type (
- tuple_expr->get_mappings ().get_hirid (), &tuple_expr_ty);
- rust_assert (ok);
-
- // do we need to add an indirect reference
- if (tuple_expr_ty->get_kind () == TyTy::TypeKind::REF)
- {
- tree indirect = indirect_expression (receiver_ref, expr.get_locus ());
- receiver_ref = indirect;
- }
-
- translated
- = ctx->get_backend ()->struct_field_expression (receiver_ref, index,
- expr.get_locus ());
- }
-
- void visit (HIR::TupleExpr &expr) override
- {
- if (expr.is_unit ())
- {
- translated = ctx->get_backend ()->unit_expression ();
- return;
- }
-
- TyTy::BaseType *tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for this TupleExpr");
- return;
- }
-
- tree tuple_type = TyTyResolveCompile::compile (ctx, tyty);
- rust_assert (tuple_type != nullptr);
-
- // this assumes all fields are in order from type resolution
- std::vector<tree> vals;
- for (auto &elem : expr.get_tuple_elems ())
- {
- auto e = CompileExpr::Compile (elem.get (), ctx);
- vals.push_back (e);
- }
-
- translated
- = ctx->get_backend ()->constructor_expression (tuple_type, false, vals,
- -1, expr.get_locus ());
- }
-
- void visit (HIR::ReturnExpr &expr) override
- {
- auto fncontext = ctx->peek_fn ();
-
- std::vector<tree> retstmts;
- if (expr.has_return_expr ())
- {
- tree compiled_expr
- = CompileExpr::Compile (expr.return_expr.get (), ctx);
- rust_assert (compiled_expr != nullptr);
-
- retstmts.push_back (compiled_expr);
- }
-
- auto s = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts,
- expr.get_locus ());
- ctx->add_statement (s);
- }
+ static tree Compile (HIR::Expr *expr, Context *ctx);
+ void visit (HIR::TupleIndexExpr &expr) override;
+ void visit (HIR::TupleExpr &expr) override;
+ void visit (HIR::ReturnExpr &expr) override;
void visit (HIR::CallExpr &expr) override;
-
void visit (HIR::MethodCallExpr &expr) override;
-
- void visit (HIR::LiteralExpr &expr) override
- {
- TyTy::BaseType *tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &tyty))
- return;
-
- switch (expr.get_lit_type ())
- {
- case HIR::Literal::BOOL:
- translated = compile_bool_literal (expr, tyty);
- return;
-
- case HIR::Literal::INT:
- translated = compile_integer_literal (expr, tyty);
- return;
-
- case HIR::Literal::FLOAT:
- translated = compile_float_literal (expr, tyty);
- return;
-
- case HIR::Literal::CHAR:
- translated = compile_char_literal (expr, tyty);
- return;
-
- case HIR::Literal::BYTE:
- translated = compile_byte_literal (expr, tyty);
- return;
-
- case HIR::Literal::STRING:
- translated = compile_string_literal (expr, tyty);
- return;
-
- case HIR::Literal::BYTE_STRING:
- translated = compile_byte_string_literal (expr, tyty);
- return;
- }
- }
-
- void visit (HIR::AssignmentExpr &expr) override
- {
- auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
- auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
-
- // assignments are coercion sites so lets convert the rvalue if necessary
- TyTy::BaseType *expected = nullptr;
- TyTy::BaseType *actual = nullptr;
-
- bool ok;
- ok = ctx->get_tyctx ()->lookup_type (
- expr.get_lhs ()->get_mappings ().get_hirid (), &expected);
- rust_assert (ok);
-
- ok = ctx->get_tyctx ()->lookup_type (
- expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
- rust_assert (ok);
-
- rvalue = coercion_site (expr.get_mappings ().get_hirid (), rvalue, actual,
- expected, expr.get_lhs ()->get_locus (),
- expr.get_rhs ()->get_locus ());
-
- tree assignment
- = ctx->get_backend ()->assignment_statement (lvalue, rvalue,
- expr.get_locus ());
-
- ctx->add_statement (assignment);
- }
-
+ void visit (HIR::LiteralExpr &expr) override;
+ void visit (HIR::AssignmentExpr &expr) override;
void visit (HIR::CompoundAssignmentExpr &expr) override;
-
void visit (HIR::ArrayIndexExpr &expr) override;
-
void visit (HIR::ArrayExpr &expr) override;
-
void visit (HIR::ArithmeticOrLogicalExpr &expr) override;
-
- void visit (HIR::ComparisonExpr &expr) override
- {
- auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
- auto location = expr.get_locus ();
-
- translated
- = ctx->get_backend ()->comparison_expression (op, lhs, rhs, location);
- }
-
- void visit (HIR::LazyBooleanExpr &expr) override
- {
- auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
- auto location = expr.get_locus ();
-
- translated
- = ctx->get_backend ()->lazy_boolean_expression (op, lhs, rhs, location);
- }
-
+ void visit (HIR::ComparisonExpr &expr) override;
+ void visit (HIR::LazyBooleanExpr &expr) override;
void visit (HIR::NegationExpr &expr) override;
-
- void visit (HIR::TypeCastExpr &expr) override
- {
- TyTy::BaseType *tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &tyty))
- {
- translated = error_mark_node;
- return;
- }
-
- auto type_to_cast_to = TyTyResolveCompile::compile (ctx, tyty);
- auto casted_expr
- = CompileExpr::Compile (expr.get_casted_expr ().get (), ctx);
- translated
- = type_cast_expression (type_to_cast_to, casted_expr, expr.get_locus ());
- }
-
- void visit (HIR::IfExpr &expr) override
- {
- auto stmt = CompileConditionalBlocks::compile (&expr, ctx, nullptr);
- ctx->add_statement (stmt);
- }
-
- void visit (HIR::IfExprConseqElse &expr) override
- {
- TyTy::BaseType *if_type = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &if_type))
- {
- rust_error_at (expr.get_locus (),
- "failed to lookup type of IfExprConseqElse");
- return;
- }
-
- Bvariable *tmp = NULL;
- bool needs_temp = !if_type->is_unit ();
- if (needs_temp)
- {
- fncontext fnctx = ctx->peek_fn ();
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, if_type);
-
- bool is_address_taken = false;
- tree ret_var_stmt = nullptr;
- tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
-
- auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp);
- ctx->add_statement (stmt);
-
- if (tmp != NULL)
- {
- translated
- = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
- }
- }
-
- void visit (HIR::IfExprConseqIf &expr) override
- {
- TyTy::BaseType *if_type = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &if_type))
- {
- rust_error_at (expr.get_locus (),
- "failed to lookup type of IfExprConseqElse");
- return;
- }
-
- Bvariable *tmp = NULL;
- bool needs_temp = !if_type->is_unit ();
- if (needs_temp)
- {
- fncontext fnctx = ctx->peek_fn ();
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, if_type);
-
- bool is_address_taken = false;
- tree ret_var_stmt = nullptr;
- tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
-
- auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp);
- ctx->add_statement (stmt);
-
- if (tmp != NULL)
- {
- translated
- = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
- }
- }
-
- void visit (HIR::BlockExpr &expr) override
- {
- TyTy::BaseType *block_tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &block_tyty))
- {
- rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
- return;
- }
-
- Bvariable *tmp = NULL;
- bool needs_temp = !block_tyty->is_unit ();
- if (needs_temp)
- {
- fncontext fnctx = ctx->peek_fn ();
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
-
- bool is_address_taken = false;
- tree ret_var_stmt = nullptr;
- tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
-
- auto block_stmt = CompileBlock::compile (&expr, ctx, tmp);
- rust_assert (TREE_CODE (block_stmt) == BIND_EXPR);
- ctx->add_statement (block_stmt);
-
- if (tmp != NULL)
- {
- translated
- = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
- }
- }
-
- void visit (HIR::UnsafeBlockExpr &expr) override
- {
- expr.get_block_expr ()->accept_vis (*this);
- }
-
- void visit (HIR::StructExprStruct &struct_expr) override
- {
- TyTy::BaseType *tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- struct_expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_error_at (struct_expr.get_locus (), "unknown type");
- return;
- }
-
- rust_assert (tyty->is_unit ());
- translated = ctx->get_backend ()->unit_expression ();
- }
-
- void visit (HIR::StructExprStructFields &struct_expr) override
- {
- TyTy::BaseType *tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- struct_expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_error_at (struct_expr.get_locus (), "unknown type");
- return;
- }
-
- // it must be an ADT
- rust_assert (tyty->get_kind () == TyTy::TypeKind::ADT);
- TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyty);
-
- // what variant is it?
- int union_disriminator = struct_expr.union_index;
- TyTy::VariantDef *variant = nullptr;
- if (!adt->is_enum ())
- {
- rust_assert (adt->number_of_variants () == 1);
- variant = adt->get_variants ().at (0);
- }
- else
- {
- HirId variant_id;
- bool ok = ctx->get_tyctx ()->lookup_variant_definition (
- struct_expr.get_struct_name ().get_mappings ().get_hirid (),
- &variant_id);
- rust_assert (ok);
-
- ok = adt->lookup_variant_by_id (variant_id, &variant,
- &union_disriminator);
- rust_assert (ok);
- }
-
- // compile it
- tree compiled_adt_type = TyTyResolveCompile::compile (ctx, tyty);
-
- std::vector<tree> arguments;
- if (adt->is_union ())
- {
- rust_assert (struct_expr.get_fields ().size () == 1);
-
- // assignments are coercion sites so lets convert the rvalue if
- // necessary
- auto respective_field
- = variant->get_field_at_index (union_disriminator);
- auto expected = respective_field->get_field_type ();
-
- // process arguments
- auto &argument = struct_expr.get_fields ().at (0);
- auto lvalue_locus
- = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
- auto rvalue_locus = argument->get_locus ();
- auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
-
- TyTy::BaseType *actual = nullptr;
- bool ok = ctx->get_tyctx ()->lookup_type (
- argument->get_mappings ().get_hirid (), &actual);
-
- if (ok)
- {
- rvalue
- = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
- actual, expected, lvalue_locus, rvalue_locus);
- }
-
- // add it to the list
- arguments.push_back (rvalue);
- }
- else
- {
- // this assumes all fields are in order from type resolution and if a
- // base struct was specified those fields are filed via accesors
- for (size_t i = 0; i < struct_expr.get_fields ().size (); i++)
- {
- // assignments are coercion sites so lets convert the rvalue if
- // necessary
- auto respective_field = variant->get_field_at_index (i);
- auto expected = respective_field->get_field_type ();
-
- // process arguments
- auto &argument = struct_expr.get_fields ().at (i);
- auto lvalue_locus
- = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
- auto rvalue_locus = argument->get_locus ();
- auto rvalue
- = CompileStructExprField::Compile (argument.get (), ctx);
-
- TyTy::BaseType *actual = nullptr;
- bool ok = ctx->get_tyctx ()->lookup_type (
- argument->get_mappings ().get_hirid (), &actual);
-
- // coerce it if required/possible see
- // compile/torture/struct_base_init_1.rs
- if (ok)
- {
- rvalue = coercion_site (argument->get_mappings ().get_hirid (),
- rvalue, actual, expected, lvalue_locus,
- rvalue_locus);
- }
-
- // add it to the list
- arguments.push_back (rvalue);
- }
- }
-
- // the constructor depends on whether this is actually an enum or not if
- // its an enum we need to setup the discriminator
- std::vector<tree> ctor_arguments;
- if (adt->is_enum ())
- {
- HIR::Expr *discrim_expr = variant->get_discriminant ();
- tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
- tree folded_discrim_expr = fold_expr (discrim_expr_node);
- tree qualifier = folded_discrim_expr;
-
- ctor_arguments.push_back (qualifier);
- }
- for (auto &arg : arguments)
- ctor_arguments.push_back (arg);
-
- translated = ctx->get_backend ()->constructor_expression (
- compiled_adt_type, adt->is_enum (), ctor_arguments, union_disriminator,
- struct_expr.get_locus ());
- }
-
- void visit (HIR::GroupedExpr &expr) override
- {
- translated = CompileExpr::Compile (expr.get_expr_in_parens ().get (), ctx);
- }
-
- void visit (HIR::FieldAccessExpr &expr) override
- {
- HIR::Expr *receiver_expr = expr.get_receiver_expr ().get ();
- tree receiver_ref = CompileExpr::Compile (receiver_expr, ctx);
-
- // resolve the receiver back to ADT type
- TyTy::BaseType *receiver = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
- {
- rust_error_at (expr.get_receiver_expr ()->get_locus (),
- "unresolved type for receiver");
- return;
- }
-
- size_t field_index = 0;
- if (receiver->get_kind () == TyTy::TypeKind::ADT)
- {
- TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver);
- rust_assert (!adt->is_enum ());
- rust_assert (adt->number_of_variants () == 1);
-
- TyTy::VariantDef *variant = adt->get_variants ().at (0);
- bool ok = variant->lookup_field (expr.get_field_name (), nullptr,
- &field_index);
- rust_assert (ok);
- }
- else if (receiver->get_kind () == TyTy::TypeKind::REF)
- {
- TyTy::ReferenceType *r = static_cast<TyTy::ReferenceType *> (receiver);
- TyTy::BaseType *b = r->get_base ();
- rust_assert (b->get_kind () == TyTy::TypeKind::ADT);
-
- TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (b);
- rust_assert (!adt->is_enum ());
- rust_assert (adt->number_of_variants () == 1);
-
- TyTy::VariantDef *variant = adt->get_variants ().at (0);
- bool ok = variant->lookup_field (expr.get_field_name (), nullptr,
- &field_index);
- rust_assert (ok);
-
- tree indirect = indirect_expression (receiver_ref, expr.get_locus ());
- receiver_ref = indirect;
- }
-
- translated
- = ctx->get_backend ()->struct_field_expression (receiver_ref, field_index,
- expr.get_locus ());
- }
-
- void visit (HIR::QualifiedPathInExpression &expr) override
- {
- translated = ResolvePathRef::Compile (expr, ctx);
- }
-
- void visit (HIR::PathInExpression &expr) override
- {
- translated = ResolvePathRef::Compile (expr, ctx);
- }
-
- void visit (HIR::LoopExpr &expr) override
- {
- TyTy::BaseType *block_tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &block_tyty))
- {
- rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
- return;
- }
-
- fncontext fnctx = ctx->peek_fn ();
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
-
- bool is_address_taken = false;
- tree ret_var_stmt = NULL_TREE;
- Bvariable *tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- ctx->push_loop_context (tmp);
-
- if (expr.has_loop_label ())
- {
- HIR::LoopLabel &loop_label = expr.get_loop_label ();
- tree label
- = ctx->get_backend ()->label (fnctx.fndecl,
- loop_label.get_lifetime ().get_name (),
- loop_label.get_locus ());
- tree label_decl
- = ctx->get_backend ()->label_definition_statement (label);
- ctx->add_statement (label_decl);
- ctx->insert_label_decl (
- loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
- }
-
- tree loop_begin_label
- = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
- tree loop_begin_label_decl
- = ctx->get_backend ()->label_definition_statement (loop_begin_label);
- ctx->add_statement (loop_begin_label_decl);
- ctx->push_loop_begin_label (loop_begin_label);
-
- tree code_block
- = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
- tree loop_expr
- = ctx->get_backend ()->loop_expression (code_block, expr.get_locus ());
- ctx->add_statement (loop_expr);
-
- ctx->pop_loop_context ();
- translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
-
- ctx->pop_loop_begin_label ();
- }
-
- void visit (HIR::WhileLoopExpr &expr) override
- {
- fncontext fnctx = ctx->peek_fn ();
- if (expr.has_loop_label ())
- {
- HIR::LoopLabel &loop_label = expr.get_loop_label ();
- tree label
- = ctx->get_backend ()->label (fnctx.fndecl,
- loop_label.get_lifetime ().get_name (),
- loop_label.get_locus ());
- tree label_decl
- = ctx->get_backend ()->label_definition_statement (label);
- ctx->add_statement (label_decl);
- ctx->insert_label_decl (
- loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
- }
-
- std::vector<Bvariable *> locals;
- Location start_location = expr.get_loop_block ()->get_locus ();
- Location end_location = expr.get_loop_block ()->get_locus (); // FIXME
-
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree loop_block
- = ctx->get_backend ()->block (fnctx.fndecl, enclosing_scope, locals,
- start_location, end_location);
- ctx->push_block (loop_block);
-
- tree loop_begin_label
- = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
- tree loop_begin_label_decl
- = ctx->get_backend ()->label_definition_statement (loop_begin_label);
- ctx->add_statement (loop_begin_label_decl);
- ctx->push_loop_begin_label (loop_begin_label);
-
- tree condition
- = CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
- tree exit_expr
- = ctx->get_backend ()->exit_expression (condition, expr.get_locus ());
- ctx->add_statement (exit_expr);
-
- tree code_block_stmt
- = CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
- rust_assert (TREE_CODE (code_block_stmt) == BIND_EXPR);
- ctx->add_statement (code_block_stmt);
-
- ctx->pop_loop_begin_label ();
- ctx->pop_block ();
-
- tree loop_expr
- = ctx->get_backend ()->loop_expression (loop_block, expr.get_locus ());
- ctx->add_statement (loop_expr);
- }
-
- void visit (HIR::BreakExpr &expr) override
- {
- if (expr.has_break_expr ())
- {
- tree compiled_expr
- = CompileExpr::Compile (expr.get_expr ().get (), ctx);
-
- Bvariable *loop_result_holder = ctx->peek_loop_context ();
- tree result_reference = ctx->get_backend ()->var_expression (
- loop_result_holder, expr.get_expr ()->get_locus ());
-
- tree assignment
- = ctx->get_backend ()->assignment_statement (result_reference,
- compiled_expr,
- expr.get_locus ());
- ctx->add_statement (assignment);
- }
-
- if (expr.has_label ())
- {
- NodeId resolved_node_id = UNKNOWN_NODEID;
- if (!ctx->get_resolver ()->lookup_resolved_label (
- expr.get_label ().get_mappings ().get_nodeid (),
- &resolved_node_id))
- {
- rust_error_at (
- expr.get_label ().get_locus (),
- "failed to resolve compiled label for label %s",
- expr.get_label ().get_mappings ().as_string ().c_str ());
- return;
- }
-
- HirId ref = UNKNOWN_HIRID;
- if (!ctx->get_mappings ()->lookup_node_to_hir (resolved_node_id, &ref))
- {
- rust_fatal_error (expr.get_locus (),
- "reverse lookup label failure");
- return;
- }
-
- tree label = NULL_TREE;
- if (!ctx->lookup_label_decl (ref, &label))
- {
- rust_error_at (expr.get_label ().get_locus (),
- "failed to lookup compiled label");
- return;
- }
-
- tree goto_label
- = ctx->get_backend ()->goto_statement (label, expr.get_locus ());
- ctx->add_statement (goto_label);
- }
- else
- {
- tree exit_expr = ctx->get_backend ()->exit_expression (
- ctx->get_backend ()->boolean_constant_expression (true),
- expr.get_locus ());
- ctx->add_statement (exit_expr);
- }
- }
-
- void visit (HIR::ContinueExpr &expr) override
- {
- tree label = ctx->peek_loop_begin_label ();
- if (expr.has_label ())
- {
- NodeId resolved_node_id = UNKNOWN_NODEID;
- if (!ctx->get_resolver ()->lookup_resolved_label (
- expr.get_label ().get_mappings ().get_nodeid (),
- &resolved_node_id))
- {
- rust_error_at (
- expr.get_label ().get_locus (),
- "failed to resolve compiled label for label %s",
- expr.get_label ().get_mappings ().as_string ().c_str ());
- return;
- }
-
- HirId ref = UNKNOWN_HIRID;
- if (!ctx->get_mappings ()->lookup_node_to_hir (resolved_node_id, &ref))
- {
- rust_fatal_error (expr.get_locus (),
- "reverse lookup label failure");
- return;
- }
-
- if (!ctx->lookup_label_decl (ref, &label))
- {
- rust_error_at (expr.get_label ().get_locus (),
- "failed to lookup compiled label");
- return;
- }
- }
-
- translated = ctx->get_backend ()->goto_statement (label, expr.get_locus ());
- }
-
+ void visit (HIR::TypeCastExpr &expr) override;
+ void visit (HIR::IfExpr &expr) override;
+ void visit (HIR::IfExprConseqIf &expr) override;
+ void visit (HIR::IfExprConseqElse &expr) override;
+ void visit (HIR::BlockExpr &expr) override;
+ void visit (HIR::UnsafeBlockExpr &expr) override;
+ void visit (HIR::StructExprStruct &struct_expr) override;
+ void visit (HIR::StructExprStructFields &struct_expr) override;
+ void visit (HIR::GroupedExpr &expr) override;
+ void visit (HIR::FieldAccessExpr &expr) override;
+ void visit (HIR::QualifiedPathInExpression &expr) override;
+ void visit (HIR::PathInExpression &expr) override;
+ void visit (HIR::LoopExpr &expr) override;
+ void visit (HIR::WhileLoopExpr &expr) override;
+ void visit (HIR::BreakExpr &expr) override;
+ void visit (HIR::ContinueExpr &expr) override;
void visit (HIR::BorrowExpr &expr) override;
void visit (HIR::DereferenceExpr &expr) override;
void visit (HIR::MatchExpr &expr) override;
-
void visit (HIR::RangeFromToExpr &expr) override;
-
void visit (HIR::RangeFromExpr &expr) override;
-
void visit (HIR::RangeToExpr &expr) override;
-
void visit (HIR::RangeFullExpr &expr) override;
-
void visit (HIR::RangeFromToInclExpr &expr) override;
// Empty visit for unused Expression HIR nodes.
@@ -852,9 +137,7 @@ protected:
HIR::ArrayElemsCopied &elems);
private:
- CompileExpr (Context *ctx)
- : HIRCompileBase (ctx), translated (error_mark_node)
- {}
+ CompileExpr (Context *ctx);
tree translated;
};
diff --git a/gcc/rust/backend/rust-compile-fnparam.cc b/gcc/rust/backend/rust-compile-fnparam.cc
index b1b5523..3f0ec82 100644
--- a/gcc/rust/backend/rust-compile-fnparam.cc
+++ b/gcc/rust/backend/rust-compile-fnparam.cc
@@ -24,6 +24,51 @@
namespace Rust {
namespace Compile {
+CompileFnParam::CompileFnParam (Context *ctx, tree fndecl, tree decl_type,
+ Location locus)
+ : HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type), locus (locus),
+ compiled_param (ctx->get_backend ()->error_variable ())
+{}
+
+Bvariable *
+CompileFnParam::compile (Context *ctx, tree fndecl, HIR::FunctionParam *param,
+ tree decl_type, Location locus)
+{
+ CompileFnParam compiler (ctx, fndecl, decl_type, locus);
+ param->get_param_name ()->accept_vis (compiler);
+ return compiler.compiled_param;
+}
+
+Bvariable *
+CompileFnParam::compile (Context *ctx, tree fndecl, HIR::Pattern *param,
+ tree decl_type, Location locus)
+{
+ CompileFnParam compiler (ctx, fndecl, decl_type, locus);
+ param->accept_vis (compiler);
+ return compiler.compiled_param;
+}
+
+void
+CompileFnParam::visit (HIR::IdentifierPattern &pattern)
+{
+ if (!pattern.is_mut ())
+ decl_type = ctx->get_backend ()->immutable_type (decl_type);
+
+ compiled_param
+ = ctx->get_backend ()->parameter_variable (fndecl,
+ pattern.get_identifier (),
+ decl_type, locus);
+}
+
+void
+CompileFnParam::visit (HIR::WildcardPattern &pattern)
+{
+ decl_type = ctx->get_backend ()->immutable_type (decl_type);
+
+ compiled_param
+ = ctx->get_backend ()->parameter_variable (fndecl, "_", decl_type, locus);
+}
+
void
CompileFnParam::visit (HIR::StructPattern &pattern)
{
@@ -58,5 +103,19 @@ CompileFnParam::visit (HIR::TupleStructPattern &pattern)
CompilePatternBindings::Compile (&pattern, anon_param, ctx);
}
+Bvariable *
+CompileSelfParam::compile (Context *ctx, tree fndecl, HIR::SelfParam &self,
+ tree decl_type, Location locus)
+{
+ bool is_immutable
+ = self.get_self_kind () == HIR::SelfParam::ImplicitSelfKind::IMM
+ || self.get_self_kind () == HIR::SelfParam::ImplicitSelfKind::IMM_REF;
+ if (is_immutable)
+ decl_type = ctx->get_backend ()->immutable_type (decl_type);
+
+ return ctx->get_backend ()->parameter_variable (fndecl, "self", decl_type,
+ locus);
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index 7c4a43a..0dbbd99 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -24,45 +24,17 @@
namespace Rust {
namespace Compile {
-class CompileFnParam : public HIRCompileBase, public HIR::HIRPatternVisitor
+class CompileFnParam : private HIRCompileBase, protected HIR::HIRPatternVisitor
{
public:
static Bvariable *compile (Context *ctx, tree fndecl,
HIR::FunctionParam *param, tree decl_type,
- Location locus)
- {
- CompileFnParam compiler (ctx, fndecl, decl_type, locus);
- param->get_param_name ()->accept_vis (compiler);
- return compiler.compiled_param;
- }
-
+ Location locus);
static Bvariable *compile (Context *ctx, tree fndecl, HIR::Pattern *param,
- tree decl_type, Location locus)
- {
- CompileFnParam compiler (ctx, fndecl, decl_type, locus);
- param->accept_vis (compiler);
- return compiler.compiled_param;
- }
-
- void visit (HIR::IdentifierPattern &pattern) override
- {
- if (!pattern.is_mut ())
- decl_type = ctx->get_backend ()->immutable_type (decl_type);
-
- compiled_param
- = ctx->get_backend ()->parameter_variable (fndecl,
- pattern.get_identifier (),
- decl_type, locus);
- }
-
- void visit (HIR::WildcardPattern &pattern) override
- {
- decl_type = ctx->get_backend ()->immutable_type (decl_type);
-
- compiled_param
- = ctx->get_backend ()->parameter_variable (fndecl, "_", decl_type, locus);
- }
+ tree decl_type, Location locus);
+ void visit (HIR::IdentifierPattern &pattern) override;
+ void visit (HIR::WildcardPattern &pattern) override;
void visit (HIR::StructPattern &) override;
void visit (HIR::TupleStructPattern &) override;
@@ -77,10 +49,7 @@ public:
void visit (HIR::TuplePattern &) override {}
private:
- CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus)
- : HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type),
- locus (locus), compiled_param (ctx->get_backend ()->error_variable ())
- {}
+ CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus);
tree fndecl;
tree decl_type;
@@ -88,21 +57,11 @@ private:
Bvariable *compiled_param;
};
-class CompileSelfParam : public HIRCompileBase, public HIR::HIRStmtVisitor
+class CompileSelfParam : private HIRCompileBase
{
public:
static Bvariable *compile (Context *ctx, tree fndecl, HIR::SelfParam &self,
- tree decl_type, Location locus)
- {
- bool is_immutable
- = self.get_self_kind () == HIR::SelfParam::ImplicitSelfKind::IMM
- || self.get_self_kind () == HIR::SelfParam::ImplicitSelfKind::IMM_REF;
- if (is_immutable)
- decl_type = ctx->get_backend ()->immutable_type (decl_type);
-
- return ctx->get_backend ()->parameter_variable (fndecl, "self", decl_type,
- locus);
- }
+ tree decl_type, Location locus);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 63316b9..3c12f10 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -24,7 +24,7 @@
namespace Rust {
namespace Compile {
-class CompileItem : public HIRCompileBase, public HIR::HIRStmtVisitor
+class CompileItem : private HIRCompileBase, protected HIR::HIRStmtVisitor
{
protected:
public:
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 7e7fadd..1d8eda1 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -18,10 +18,9 @@
#include "rust-compile-pattern.h"
#include "rust-compile-expr.h"
+#include "rust-compile-resolve-path.h"
#include "rust-constexpr.h"
-#include "print-tree.h"
-
namespace Rust {
namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index f799445..4fb3d54 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -24,6 +24,7 @@
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
#include "rust-compile-extern.h"
+#include "rust-constexpr.h"
namespace Rust {
namespace Compile {
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
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 9bb4b7b..a0ec8b2 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -20,94 +20,18 @@
#define RUST_COMPILE_STMT
#include "rust-compile-base.h"
-#include "rust-compile-expr.h"
namespace Rust {
namespace Compile {
-class CompileStmt : public HIRCompileBase, public HIR::HIRStmtVisitor
+class CompileStmt : private HIRCompileBase, protected HIR::HIRStmtVisitor
{
public:
- static tree Compile (HIR::Stmt *stmt, Context *ctx)
- {
- CompileStmt compiler (ctx);
- stmt->accept_vis (compiler);
- return compiler.translated;
- }
+ static tree Compile (HIR::Stmt *stmt, Context *ctx);
- void visit (HIR::ExprStmtWithBlock &stmt) override
- {
- translated = CompileExpr::Compile (stmt.get_expr (), ctx);
- }
-
- void visit (HIR::ExprStmtWithoutBlock &stmt) override
- {
- translated = CompileExpr::Compile (stmt.get_expr (), ctx);
- }
-
- void visit (HIR::LetStmt &stmt) override
- {
- // 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);
- }
- }
+ void visit (HIR::ExprStmtWithBlock &stmt) override;
+ void visit (HIR::ExprStmtWithoutBlock &stmt) override;
+ void visit (HIR::LetStmt &stmt) override;
// Empty visit for unused Stmt HIR nodes.
void visit (HIR::TupleStruct &) override {}
@@ -134,7 +58,7 @@ public:
void visit (HIR::EmptyStmt &) override {}
private:
- CompileStmt (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
+ CompileStmt (Context *ctx);
tree translated;
};
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.cc b/gcc/rust/backend/rust-compile-struct-field-expr.cc
new file mode 100644
index 0000000..c9a2811
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.cc
@@ -0,0 +1,81 @@
+// 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-struct-field-expr.h"
+#include "rust-compile-expr.h"
+
+namespace Rust {
+namespace Compile {
+
+CompileStructExprField::CompileStructExprField (Context *ctx)
+ : HIRCompileBase (ctx), translated (error_mark_node)
+{}
+
+tree
+CompileStructExprField::Compile (HIR::StructExprField *field, Context *ctx)
+{
+ CompileStructExprField compiler (ctx);
+ switch (field->get_kind ())
+ {
+ case HIR::StructExprField::StructExprFieldKind::IDENTIFIER:
+ compiler.visit (static_cast<HIR::StructExprFieldIdentifier &> (*field));
+ break;
+
+ case HIR::StructExprField::StructExprFieldKind::IDENTIFIER_VALUE:
+ compiler.visit (
+ static_cast<HIR::StructExprFieldIdentifierValue &> (*field));
+ break;
+
+ case HIR::StructExprField::StructExprFieldKind::INDEX_VALUE:
+ compiler.visit (static_cast<HIR::StructExprFieldIndexValue &> (*field));
+ break;
+ }
+ return compiler.translated;
+}
+
+void
+CompileStructExprField::visit (HIR::StructExprFieldIdentifierValue &field)
+{
+ translated = CompileExpr::Compile (field.get_value (), ctx);
+}
+
+void
+CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field)
+{
+ translated = CompileExpr::Compile (field.get_value (), ctx);
+}
+
+void
+CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
+{
+ // we can make the field look like a path expr to take advantage of existing
+ // code
+
+ Analysis::NodeMapping mappings_copy1 = field.get_mappings ();
+ Analysis::NodeMapping mappings_copy2 = field.get_mappings ();
+
+ HIR::PathIdentSegment ident_seg (field.get_field_name ());
+ HIR::PathExprSegment seg (mappings_copy1, ident_seg, field.get_locus (),
+ HIR::GenericArgs::create_empty ());
+ HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
+ {});
+ translated = CompileExpr::Compile (&expr, ctx);
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h
index 90c3140..bc5da08 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.h
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.h
@@ -24,79 +24,18 @@
namespace Rust {
namespace Compile {
-class CompileStructExprField : public HIRCompileBase,
- public HIR::HIRExpressionVisitor
+class CompileStructExprField : private HIRCompileBase
{
public:
- static tree Compile (HIR::StructExprField *field, Context *ctx)
- {
- CompileStructExprField compiler (ctx);
- field->accept_vis (compiler);
- rust_assert (compiler.translated != nullptr);
- return compiler.translated;
- }
+ static tree Compile (HIR::StructExprField *field, Context *ctx);
- void visit (HIR::StructExprFieldIdentifierValue &field) override;
- void visit (HIR::StructExprFieldIndexValue &field) override;
- void visit (HIR::StructExprFieldIdentifier &field) override;
-
- // Empty visit for unused Expression HIR nodes.
- void visit (HIR::PathInExpression &) override {}
- void visit (HIR::QualifiedPathInExpression &) override {}
- void visit (HIR::ClosureExprInner &) override {}
- void visit (HIR::ClosureExprInnerTyped &) override {}
- void visit (HIR::StructExprStruct &) override {}
- void visit (HIR::StructExprStructFields &) override {}
- void visit (HIR::LiteralExpr &) override {}
- void visit (HIR::BorrowExpr &) override {}
- void visit (HIR::DereferenceExpr &) override {}
- void visit (HIR::ErrorPropagationExpr &) override {}
- void visit (HIR::NegationExpr &) override {}
- void visit (HIR::ArithmeticOrLogicalExpr &) override {}
- void visit (HIR::ComparisonExpr &) override {}
- void visit (HIR::LazyBooleanExpr &) override {}
- void visit (HIR::TypeCastExpr &) override {}
- void visit (HIR::AssignmentExpr &) override {}
- void visit (HIR::CompoundAssignmentExpr &) override {}
- void visit (HIR::GroupedExpr &) override {}
- void visit (HIR::ArrayExpr &) override {}
- void visit (HIR::ArrayIndexExpr &) override {}
- void visit (HIR::TupleExpr &) override {}
- void visit (HIR::TupleIndexExpr &) override {}
- void visit (HIR::CallExpr &) override {}
- void visit (HIR::MethodCallExpr &) override {}
- void visit (HIR::FieldAccessExpr &) override {}
- void visit (HIR::BlockExpr &) override {}
- void visit (HIR::ContinueExpr &) override {}
- void visit (HIR::BreakExpr &) override {}
- void visit (HIR::RangeFromToExpr &) override {}
- void visit (HIR::RangeFromExpr &) override {}
- void visit (HIR::RangeToExpr &) override {}
- void visit (HIR::RangeFullExpr &) override {}
- void visit (HIR::RangeFromToInclExpr &) override {}
- void visit (HIR::RangeToInclExpr &) override {}
- void visit (HIR::ReturnExpr &) override {}
- void visit (HIR::UnsafeBlockExpr &) override {}
- void visit (HIR::LoopExpr &) override {}
- void visit (HIR::WhileLoopExpr &) override {}
- void visit (HIR::WhileLetLoopExpr &) override {}
- void visit (HIR::ForLoopExpr &) override {}
- void visit (HIR::IfExpr &) override {}
- void visit (HIR::IfExprConseqElse &) override {}
- void visit (HIR::IfExprConseqIf &) override {}
- void visit (HIR::IfExprConseqIfLet &) override {}
- void visit (HIR::IfLetExpr &) override {}
- void visit (HIR::IfLetExprConseqElse &) override {}
- void visit (HIR::IfLetExprConseqIf &) override {}
- void visit (HIR::IfLetExprConseqIfLet &) override {}
- void visit (HIR::MatchExpr &) override {}
- void visit (HIR::AwaitExpr &) override {}
- void visit (HIR::AsyncBlockExpr &) override {}
+protected:
+ void visit (HIR::StructExprFieldIdentifierValue &field);
+ void visit (HIR::StructExprFieldIndexValue &field);
+ void visit (HIR::StructExprFieldIdentifier &field);
private:
- CompileStructExprField (Context *ctx)
- : HIRCompileBase (ctx), translated (nullptr)
- {}
+ CompileStructExprField (Context *ctx);
tree translated;
};
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index c9b6b62..b52fd71 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -24,7 +24,7 @@
namespace Rust {
namespace Compile {
-class TyTyResolveCompile : public TyTy::TyConstVisitor
+class TyTyResolveCompile : protected TyTy::TyConstVisitor
{
public:
static tree compile (Context *ctx, const TyTy::BaseType *ty,
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index c4100c4..6913144 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -16,16 +16,17 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include "rust-hir-trait-resolve.h"
-#include "rust-hir-path-probe.h"
-#include "rust-hir-type-bounds.h"
-#include "rust-hir-dot-operator.h"
#include "rust-compile.h"
#include "rust-compile-item.h"
#include "rust-compile-implitem.h"
#include "rust-compile-expr.h"
#include "rust-compile-struct-field-expr.h"
#include "rust-compile-stmt.h"
+#include "rust-hir-trait-resolve.h"
+#include "rust-hir-path-probe.h"
+#include "rust-hir-type-bounds.h"
+#include "rust-hir-dot-operator.h"
+#include "rust-compile-block.h"
namespace Rust {
namespace Compile {
@@ -50,158 +51,6 @@ CompileCrate::go ()
CompileItem::compile (item.get (), ctx);
}
-// rust-compile-block.h
-
-void
-CompileBlock::visit (HIR::BlockExpr &expr)
-{
- fncontext fnctx = ctx->peek_fn ();
- tree fndecl = fnctx.fndecl;
- Location start_location = expr.get_locus ();
- Location end_location = expr.get_end_locus ();
- auto body_mappings = expr.get_mappings ();
-
- Resolver::Rib *rib = nullptr;
- if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), &rib))
- {
- rust_fatal_error (expr.get_locus (), "failed to setup locals per block");
- return;
- }
-
- std::vector<Bvariable *> locals
- = compile_locals_for_block (ctx, *rib, fndecl);
-
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree new_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
- start_location, end_location);
- ctx->push_block (new_block);
-
- for (auto &s : expr.get_statements ())
- {
- auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
- if (compiled_expr != nullptr)
- {
- tree s = convert_to_void (compiled_expr, ICV_STATEMENT);
- ctx->add_statement (s);
- }
- }
-
- if (expr.has_expr ())
- {
- // the previous passes will ensure this is a valid return or
- // a valid trailing expression
- tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
- if (compiled_expr != nullptr)
- {
- if (result == nullptr)
- {
- ctx->add_statement (compiled_expr);
- }
- else
- {
- tree result_reference = ctx->get_backend ()->var_expression (
- result, expr.get_final_expr ()->get_locus ());
-
- tree assignment
- = ctx->get_backend ()->assignment_statement (result_reference,
- compiled_expr,
- expr.get_locus ());
- ctx->add_statement (assignment);
- }
- }
- }
-
- ctx->pop_block ();
- translated = new_block;
-}
-
-void
-CompileConditionalBlocks::visit (HIR::IfExpr &expr)
-{
- fncontext fnctx = ctx->peek_fn ();
- tree fndecl = fnctx.fndecl;
- tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
- tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
-
- translated
- = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
- NULL, expr.get_locus ());
-}
-
-void
-CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
-{
- fncontext fnctx = ctx->peek_fn ();
- tree fndecl = fnctx.fndecl;
- tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
- tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
- tree else_block = CompileBlock::compile (expr.get_else_block (), ctx, result);
-
- translated
- = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
- else_block, expr.get_locus ());
-}
-
-void
-CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr)
-{
- fncontext fnctx = ctx->peek_fn ();
- tree fndecl = fnctx.fndecl;
- tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
- tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
-
- // else block
- std::vector<Bvariable *> locals;
- Location start_location = expr.get_conseq_if_expr ()->get_locus ();
- Location end_location = expr.get_conseq_if_expr ()->get_locus (); // FIXME
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree else_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
- start_location, end_location);
- ctx->push_block (else_block);
-
- tree else_stmt_decl
- = CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx,
- result);
- ctx->add_statement (else_stmt_decl);
-
- ctx->pop_block ();
-
- translated
- = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
- else_block, expr.get_locus ());
-}
-
-// rust-compile-struct-field-expr.h
-
-void
-CompileStructExprField::visit (HIR::StructExprFieldIdentifierValue &field)
-{
- translated = CompileExpr::Compile (field.get_value (), ctx);
-}
-
-void
-CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field)
-{
- translated = CompileExpr::Compile (field.get_value (), ctx);
-}
-
-void
-CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
-{
- // we can make the field look like a path expr to take advantage of existing
- // code
-
- Analysis::NodeMapping mappings_copy1 = field.get_mappings ();
- Analysis::NodeMapping mappings_copy2 = field.get_mappings ();
-
- HIR::PathIdentSegment ident_seg (field.get_field_name ());
- HIR::PathExprSegment seg (mappings_copy1, ident_seg, field.get_locus (),
- HIR::GenericArgs::create_empty ());
- HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
- {});
- translated = CompileExpr::Compile (&expr, ctx);
-}
-
// Shared methods in compilation
tree