Skip to content

Commit

Permalink
Bring conditionals back since the HIR change.
Browse files Browse the repository at this point in the history
  • Loading branch information
philberty committed Dec 23, 2020
1 parent b021811 commit aa2fbb5
Show file tree
Hide file tree
Showing 19 changed files with 733 additions and 41 deletions.
4 changes: 4 additions & 0 deletions gcc/rust/ast/rust-expr.h
Expand Up @@ -550,6 +550,8 @@ class ComparisonExpr : public OperatorExpr
return right_expr;
}

ExprType get_kind () { return expr_type; }

/* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
* maybe? */
protected:
Expand Down Expand Up @@ -628,6 +630,8 @@ class LazyBooleanExpr : public OperatorExpr
return right_expr;
}

ExprType get_kind () { return expr_type; }

protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
Expand Down
112 changes: 112 additions & 0 deletions gcc/rust/backend/rust-compile-block.h
@@ -0,0 +1,112 @@
// Copyright (C) 2020 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/>.

#ifndef RUST_COMPILE_BLOCK
#define RUST_COMPILE_BLOCK

#include "rust-compile-base.h"
#include "rust-compile-tyty.h"

namespace Rust {
namespace Compile {

class CompileBlock : public HIRCompileBase
{
public:
static Bblock *compile (HIR::BlockExpr *expr, Context *ctx)
{
CompileBlock compiler (ctx);
expr->accept_vis (compiler);
return compiler.translated;
}

~CompileBlock () {}

void visit (HIR::BlockExpr &expr);

private:
CompileBlock (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}

Bblock *translated;
};

class CompileConditionalBlocks : public HIRCompileBase
{
public:
static Bstatement *compile (HIR::IfExpr *expr, Context *ctx)
{
CompileConditionalBlocks resolver (ctx);
expr->accept_vis (resolver);
return resolver.translated;
}

~CompileConditionalBlocks () {}

void visit (HIR::IfExpr &expr);

void visit (HIR::IfExprConseqElse &expr);

void visit (HIR::IfExprConseqIf &expr);

private:
CompileConditionalBlocks (Context *ctx)
: HIRCompileBase (ctx), translated (nullptr)
{}

Bstatement *translated;
};

class CompileExprWithBlock : public HIRCompileBase
{
public:
static Bstatement *compile (HIR::ExprWithBlock *expr, Context *ctx)
{
CompileExprWithBlock resolver (ctx);
expr->accept_vis (resolver);
return resolver.translated;
}

~CompileExprWithBlock () {}

void visit (HIR::IfExpr &expr)
{
translated = CompileConditionalBlocks::compile (&expr, ctx);
}

void visit (HIR::IfExprConseqElse &expr)
{
translated = CompileConditionalBlocks::compile (&expr, ctx);
}

void visit (HIR::IfExprConseqIf &expr)
{
translated = CompileConditionalBlocks::compile (&expr, ctx);
}

private:
CompileExprWithBlock (Context *ctx)
: HIRCompileBase (ctx), translated (nullptr)
{}

Bstatement *translated;
};

} // namespace Compile
} // namespace Rust

#endif // RUST_COMPILE_BLOCK
26 changes: 26 additions & 0 deletions gcc/rust/backend/rust-compile-expr.h
Expand Up @@ -22,6 +22,7 @@
#include "rust-compile-base.h"
#include "rust-compile-tyty.h"
#include "rust-compile-resolve-path.h"
#include "rust-compile-block.h"

namespace Rust {
namespace Compile {
Expand Down Expand Up @@ -273,6 +274,31 @@ class CompileExpr : public HIRCompileBase
expr.get_locus ());
}

void visit (HIR::IfExpr &expr)
{
auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
ctx->add_statement (stmt);
}

void visit (HIR::IfExprConseqElse &expr)
{
auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
ctx->add_statement (stmt);
}

void visit (HIR::IfExprConseqIf &expr)
{
auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
ctx->add_statement (stmt);
}

void visit (HIR::BlockExpr &expr)
{
auto code_block = CompileBlock::compile (&expr, ctx);
auto block_stmt = ctx->get_backend ()->block_statement (code_block);
ctx->add_statement (block_stmt);
}

private:
CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}

Expand Down
12 changes: 12 additions & 0 deletions gcc/rust/backend/rust-compile-stmt.h
Expand Up @@ -38,6 +38,18 @@ class CompileStmt : public HIRCompileBase

virtual ~CompileStmt () {}

void visit (HIR::ExprStmtWithBlock &stmt)
{
ok = true;
auto translated = CompileExpr::Compile (stmt.get_expr (), ctx);

// these can be null
if (translated == nullptr)
return;

gcc_unreachable ();
}

void visit (HIR::ExprStmtWithoutBlock &stmt)
{
ok = true;
Expand Down
109 changes: 109 additions & 0 deletions gcc/rust/backend/rust-compile.cc
Expand Up @@ -18,6 +18,7 @@

#include "rust-compile.h"
#include "rust-compile-item.h"
#include "rust-compile-expr.h"

namespace Rust {
namespace Compile {
Expand All @@ -43,5 +44,113 @@ CompileCrate::go ()
CompileItem::compile (it->get (), ctx);
}

// rust-compile-block.h

void
CompileBlock::visit (HIR::BlockExpr &expr)
{
fncontext fnctx = ctx->peek_fn ();
Bfunction *fndecl = fnctx.fndecl;
Location start_location = expr.get_locus ();
Location end_location = expr.get_closing_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;
rib->iterate_decls ([&] (NodeId n) mutable -> bool {
Resolver::Definition d;
bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
rust_assert (ok);

HIR::Stmt *decl = nullptr;
ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
rust_assert (ok);

Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
locals.push_back (compiled);

return true;
});

Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
Bblock *new_block
= ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (new_block);

expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
CompileStmt::Compile (s, ctx);
return true;
});

ctx->pop_block ();
translated = new_block;
}

void
CompileConditionalBlocks::visit (HIR::IfExpr &expr)
{
fncontext fnctx = ctx->peek_fn ();
Bfunction *fndecl = fnctx.fndecl;
Bexpression *condition_expr
= CompileExpr::Compile (expr.get_if_condition (), ctx);
Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx);

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 ();
Bfunction *fndecl = fnctx.fndecl;
Bexpression *condition_expr
= CompileExpr::Compile (expr.get_if_condition (), ctx);
Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx);
Bblock *else_block = CompileBlock::compile (expr.get_else_block (), ctx);

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 ();
Bfunction *fndecl = fnctx.fndecl;
Bexpression *condition_expr
= CompileExpr::Compile (expr.get_if_condition (), ctx);
Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx);

// 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
Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
Bblock *else_block
= ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (else_block);

Bstatement *else_stmt_decl
= CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx);
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

0 comments on commit aa2fbb5

Please sign in to comment.