diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-11 13:42:07 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-13 09:54:32 +0000 |
commit | ebb5de23436436d4206766552e76cd4b802e0c74 (patch) | |
tree | fa7cf962d5c796e4a1c5e2dc72b6cf6345414671 /gcc/rust/backend/rust-compile-expr.h | |
parent | 7366f6decf5ff3c652844913977582c9dec68d53 (diff) | |
download | gcc-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.h | 55 |
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) {} |