aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-expr.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-11 13:42:07 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-13 09:54:32 +0000
commitebb5de23436436d4206766552e76cd4b802e0c74 (patch)
treefa7cf962d5c796e4a1c5e2dc72b6cf6345414671 /gcc/rust/backend/rust-compile-expr.h
parent7366f6decf5ff3c652844913977582c9dec68d53 (diff)
downloadgcc-ebb5de23436436d4206766552e76cd4b802e0c74.zip
gcc-ebb5de23436436d4206766552e76cd4b802e0c74.tar.gz
gcc-ebb5de23436436d4206766552e76cd4b802e0c74.tar.bz2
Add in ContinueExpr support
We made an implicit loop begin label that can be referenced in a goto to restart the loop. Fixes #188
Diffstat (limited to 'gcc/rust/backend/rust-compile-expr.h')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 1ca7631..1e4aef6 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -625,6 +625,13 @@ public:
loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
}
+ Blabel *loop_begin_label
+ = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
+ Bstatement *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);
+
Bblock *code_block
= CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
Bexpression *loop_expr
@@ -639,6 +646,7 @@ public:
translated
= ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
}
+ ctx->pop_loop_begin_label ();
}
void visit (HIR::WhileLoopExpr &expr)
@@ -668,6 +676,13 @@ public:
start_location, end_location);
ctx->push_block (loop_block);
+ Blabel *loop_begin_label
+ = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
+ Bstatement *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);
+
Bexpression *condition
= CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
Bexpression *exit_expr
@@ -682,6 +697,7 @@ public:
= ctx->get_backend ()->block_statement (code_block);
ctx->add_statement (code_block_stmt);
+ ctx->pop_loop_begin_label ();
ctx->pop_block ();
Bexpression *loop_expr
@@ -754,6 +770,45 @@ public:
}
}
+ void visit (HIR::ContinueExpr &expr)
+ {
+ Blabel *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 (
+ expr.get_mappings ().get_crate_num (), 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;
+ }
+ }
+
+ Bstatement *goto_label
+ = ctx->get_backend ()->goto_statement (label, expr.get_locus ());
+ ctx->add_statement (goto_label);
+ }
+
private:
CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}