aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-09 17:50:39 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-10 18:10:57 +0000
commit1a2c0911f0e818328a8909b1f5ba0685b6eca351 (patch)
treedb3d500a783d5794a1a190f7172d6b8205b0db4e /gcc
parentcb9998216d76ccc62b45fcf01b3a0928a026f7ed (diff)
downloadgcc-1a2c0911f0e818328a8909b1f5ba0685b6eca351.zip
gcc-1a2c0911f0e818328a8909b1f5ba0685b6eca351.tar.gz
gcc-1a2c0911f0e818328a8909b1f5ba0685b6eca351.tar.bz2
Support Simple LoopExpr
This is the building block for the rest of loops where we have a basic infinite loop. Break/Continue reliest on the resolution of labels and breaks can also make a loop into a BlockExpr Fixes #106
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h19
-rw-r--r--gcc/rust/hir/rust-ast-lower-block.h19
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h5
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h5
-rw-r--r--gcc/testsuite/rust.test/compilable/loop1.rs10
7 files changed, 65 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 2dabe01..77b8888 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -580,6 +580,25 @@ public:
translated = ResolvePathRef::Compile (&expr, ctx);
}
+ void visit (HIR::LoopExpr &expr)
+ {
+ // loop_start:
+ // <loop_body>
+ // goto loop_start;
+ fncontext fnctx = ctx->peek_fn ();
+ Blabel *loop_start
+ = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
+ Bstatement *label_decl_stmt
+ = ctx->get_backend ()->label_definition_statement (loop_start);
+ ctx->add_statement (label_decl_stmt);
+
+ translated = CompileExpr::Compile (expr.get_loop_block ().get (), ctx);
+
+ Bstatement *goto_loop_start_stmt
+ = ctx->get_backend ()->goto_statement (loop_start, Location ());
+ ctx->add_statement (goto_loop_start_stmt);
+ }
+
private:
CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h
index f81a242..d3c61df 100644
--- a/gcc/rust/hir/rust-ast-lower-block.h
+++ b/gcc/rust/hir/rust-ast-lower-block.h
@@ -134,6 +134,25 @@ public:
translated = ASTLoweringBlock::translate (&expr, &terminated);
}
+ void visit (AST::LoopExpr &expr)
+ {
+ std::vector<HIR::Attribute> outer_attribs;
+ HIR::BlockExpr *loop_block
+ = ASTLoweringBlock::translate (expr.get_loop_block ().get (),
+ &terminated);
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ translated
+ = new HIR::LoopExpr (mapping,
+ std::unique_ptr<HIR::BlockExpr> (loop_block),
+ expr.get_locus (), HIR::LoopLabel::error (),
+ std::move (outer_attribs));
+ }
+
private:
ASTLoweringExprWithBlock ()
: ASTLoweringBase (), translated (nullptr), terminated (false)
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index cd1863f..49ac7f1 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -697,6 +697,11 @@ public:
std::move (outer_attribs), expr.get_locus ());
}
+ void visit (AST::LoopExpr &expr)
+ {
+ translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
+ }
+
private:
ASTLoweringExpr ()
: translated (nullptr), translated_array_elems (nullptr), terminated (false)
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index d4af3c2..14b223a 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -3334,6 +3334,8 @@ public:
Location get_locus () const { return locus; }
Location get_locus_slow () const override { return get_locus (); }
+
+ std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
};
// 'Loop' expression (i.e. the infinite loop) HIR node
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index d563f93..e8ee8b3 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -241,6 +241,11 @@ public:
ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ());
}
+ void visit (AST::LoopExpr &expr)
+ {
+ ResolveExpr::go (expr.get_loop_block ().get (), expr.get_node_id ());
+ }
+
private:
ResolveExpr (NodeId parent) : ResolverBase (parent) {}
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index cb92332..17e79d4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -741,6 +741,11 @@ public:
}
}
+ void visit (HIR::LoopExpr &expr)
+ {
+ infered = TypeCheckExpr::Resolve (expr.get_loop_block ().get ());
+ }
+
private:
TypeCheckExpr ()
: TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr)
diff --git a/gcc/testsuite/rust.test/compilable/loop1.rs b/gcc/testsuite/rust.test/compilable/loop1.rs
new file mode 100644
index 0000000..a8ee2f5
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/loop1.rs
@@ -0,0 +1,10 @@
+fn main() {
+ let mut a = 1;
+ let mut b = 1;
+
+ loop {
+ let c = a + b;
+ a = b;
+ b = c;
+ }
+}