aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-expr.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-10 15:47:14 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-10 18:10:57 +0000
commit06c9fd97bf3d86a08eadcadb1bc59cb392116d16 (patch)
treea74de9189504af72dff442103b5a323c7a74b48b /gcc/rust/backend/rust-compile-expr.h
parentf10e695fc508c472c77e968e644f710806f82f54 (diff)
downloadgcc-06c9fd97bf3d86a08eadcadb1bc59cb392116d16.zip
gcc-06c9fd97bf3d86a08eadcadb1bc59cb392116d16.tar.gz
gcc-06c9fd97bf3d86a08eadcadb1bc59cb392116d16.tar.bz2
Support LoopLabels and break to label.
This allows for the Rust refernece example for loop labels to be compiled. Fixes #107
Diffstat (limited to 'gcc/rust/backend/rust-compile-expr.h')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h66
1 files changed, 59 insertions, 7 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 0c8d25a..189118b 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -587,6 +587,20 @@ public:
void visit (HIR::LoopExpr &expr)
{
fncontext fnctx = ctx->peek_fn ();
+ if (expr.has_loop_label ())
+ {
+ HIR::LoopLabel &loop_label = expr.get_loop_label ();
+ Blabel *label
+ = ctx->get_backend ()->label (fnctx.fndecl,
+ loop_label.get_lifetime ().get_name (),
+ loop_label.get_locus ());
+ Bstatement *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);
+ }
+
Bblock *code_block
= CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
Bexpression *loop_expr
@@ -598,13 +612,51 @@ public:
void visit (HIR::BreakExpr &expr)
{
- fncontext fnctx = ctx->peek_fn ();
- Bexpression *exit_expr = ctx->get_backend ()->exit_expression (
- ctx->get_backend ()->boolean_constant_expression (true),
- expr.get_locus ());
- Bstatement *break_stmt
- = ctx->get_backend ()->expression_statement (fnctx.fndecl, exit_expr);
- ctx->add_statement (break_stmt);
+ 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;
+ }
+
+ Blabel *label = nullptr;
+ 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);
+ }
+ else
+ {
+ fncontext fnctx = ctx->peek_fn ();
+ Bexpression *exit_expr = ctx->get_backend ()->exit_expression (
+ ctx->get_backend ()->boolean_constant_expression (true),
+ expr.get_locus ());
+ Bstatement *break_stmt
+ = ctx->get_backend ()->expression_statement (fnctx.fndecl, exit_expr);
+ ctx->add_statement (break_stmt);
+ }
}
private: