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 | |
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')
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 15 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 55 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-stmt.h | 19 |
3 files changed, 83 insertions, 6 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 288b917..76255b0 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -219,6 +219,20 @@ public: return back; } + void push_loop_begin_label (Blabel *label) + { + loop_begin_labels.push_back (label); + } + + Blabel *peek_loop_begin_label () { return loop_begin_labels.back (); } + + Blabel *pop_loop_begin_label () + { + Blabel *pop = loop_begin_labels.back (); + loop_begin_labels.pop_back (); + return pop; + } + private: ::Backend *backend; Resolver::Resolver *resolver; @@ -235,6 +249,7 @@ private: std::vector< ::std::vector<Bstatement *> > statements; std::vector< ::Bblock *> scope_stack; std::vector< ::Bvariable *> loop_value_stack; + std::vector< ::Blabel *> loop_begin_labels; // To GCC middle-end std::vector< ::Btype *> type_decls; 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) {} diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h index d021240e4..add969a 100644 --- a/gcc/rust/backend/rust-compile-stmt.h +++ b/gcc/rust/backend/rust-compile-stmt.h @@ -66,10 +66,6 @@ public: return; } - // there is an ICE in GCC for void_node - if (ty->get_kind () == TyTy::TypeKind::UNIT) - return; - Bvariable *var = nullptr; if (!ctx->lookup_var_decl (stmt.get_mappings ().get_hirid (), &var)) { @@ -79,10 +75,21 @@ public: } Bexpression *init = CompileExpr::Compile (stmt.get_init_expr (), ctx); + if (init == nullptr) + return; auto fnctx = ctx->peek_fn (); - auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var, init); - ctx->add_statement (s); + if (ty->get_kind () == TyTy::TypeKind::UNIT) + { + Bstatement *expr_stmt + = ctx->get_backend ()->expression_statement (fnctx.fndecl, init); + ctx->add_statement (expr_stmt); + } + else + { + auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var, init); + ctx->add_statement (s); + } } private: |