diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-06-23 17:22:12 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-06-24 12:36:08 +0100 |
commit | 92a434a33904608f5659cf7b5d4df3d2a99bd5bd (patch) | |
tree | 02daa3d23d04cb9c950b15d5a7a94f171e1241db /gcc/rust/backend | |
parent | 23e748d7a6855ce132299cfef9692ee9c681de59 (diff) | |
download | gcc-92a434a33904608f5659cf7b5d4df3d2a99bd5bd.zip gcc-92a434a33904608f5659cf7b5d4df3d2a99bd5bd.tar.gz gcc-92a434a33904608f5659cf7b5d4df3d2a99bd5bd.tar.bz2 |
Add support for nested functions
We missed that stmts in rust can be items like functions. This adds support
for resolution and compilation of nested functions. Rust allows nested
functions which are distinct to closures. Nested functions are not allowed
to encapsulate the enclosing scope so they can be extracted as normal functions.
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 3 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.h | 44 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 22 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 51 |
4 files changed, 49 insertions, 71 deletions
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index ed33515..c346af5 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -210,6 +210,9 @@ protected: void compile_function_body (Bfunction *fndecl, std::unique_ptr<HIR::BlockExpr> &function_body, bool has_return_type); + + bool compile_locals_for_block (Resolver::Rib &rib, Bfunction *fndecl, + std::vector<Bvariable *> &locals); }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h index d6698d1..70f76b7 100644 --- a/gcc/rust/backend/rust-compile-implitem.h +++ b/gcc/rust/backend/rust-compile-implitem.h @@ -183,26 +183,10 @@ public: } std::vector<Bvariable *> locals; - rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool { - Resolver::Definition d; - bool ok = ctx->get_resolver ()->lookup_definition (n, &d); - rust_assert (ok); - - HIR::Stmt *decl = nullptr; - ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); - rust_assert (ok); - - Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx); - locals.push_back (compiled); - - return true; - }); - - bool toplevel_item - = function.get_mappings ().get_local_defid () != UNKNOWN_LOCAL_DEFID; - Bblock *enclosing_scope - = toplevel_item ? NULL : ctx->peek_enclosing_scope (); + bool ok = compile_locals_for_block (*rib, fndecl, locals); + rust_assert (ok); + Bblock *enclosing_scope = NULL; HIR::BlockExpr *function_body = function.get_definition ().get (); Location start_location = function_body->get_locus (); Location end_location = function_body->get_closing_locus (); @@ -409,26 +393,10 @@ public: } std::vector<Bvariable *> locals; - rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool { - Resolver::Definition d; - bool ok = ctx->get_resolver ()->lookup_definition (n, &d); - rust_assert (ok); - - HIR::Stmt *decl = nullptr; - ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); - rust_assert (ok); - - Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx); - locals.push_back (compiled); - - return true; - }); - - bool toplevel_item - = method.get_mappings ().get_local_defid () != UNKNOWN_LOCAL_DEFID; - Bblock *enclosing_scope - = toplevel_item ? NULL : ctx->peek_enclosing_scope (); + bool ok = compile_locals_for_block (*rib, fndecl, locals); + rust_assert (ok); + Bblock *enclosing_scope = NULL; HIR::BlockExpr *function_body = method.get_function_body ().get (); Location start_location = function_body->get_locus (); Location end_location = function_body->get_closing_locus (); diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index 8a521e7..eacfda9 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -213,26 +213,10 @@ public: } std::vector<Bvariable *> locals; - rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool { - Resolver::Definition d; - bool ok = ctx->get_resolver ()->lookup_definition (n, &d); - rust_assert (ok); - - HIR::Stmt *decl = nullptr; - ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); - rust_assert (ok); - - Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx); - locals.push_back (compiled); - - return true; - }); - - bool toplevel_item - = function.get_mappings ().get_local_defid () != UNKNOWN_LOCAL_DEFID; - Bblock *enclosing_scope - = toplevel_item ? NULL : ctx->peek_enclosing_scope (); + bool ok = compile_locals_for_block (*rib, fndecl, locals); + rust_assert (ok); + Bblock *enclosing_scope = NULL; HIR::BlockExpr *function_body = function.get_definition ().get (); Location start_location = function_body->get_locus (); Location end_location = function_body->get_closing_locus (); diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 351271c..5ffd11a 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -212,20 +212,8 @@ CompileBlock::visit (HIR::BlockExpr &expr) } std::vector<Bvariable *> locals; - rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool { - Resolver::Definition d; - bool ok = ctx->get_resolver ()->lookup_definition (n, &d); - rust_assert (ok); - - HIR::Stmt *decl = nullptr; - ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); - rust_assert (ok); - - Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx); - locals.push_back (compiled); - - return true; - }); + bool ok = compile_locals_for_block (*rib, fndecl, locals); + rust_assert (ok); Bblock *enclosing_scope = ctx->peek_enclosing_scope (); Bblock *new_block @@ -415,6 +403,41 @@ HIRCompileBase::compile_function_body ( } } +bool +HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, Bfunction *fndecl, + std::vector<Bvariable *> &locals) +{ + rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool { + Resolver::Definition d; + bool ok = ctx->get_resolver ()->lookup_definition (n, &d); + rust_assert (ok); + + HIR::Stmt *decl = nullptr; + ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); + rust_assert (ok); + + // if its a function we extract this out side of this fn context + // and it is not a local to this function + bool is_item = ctx->get_mappings ()->lookup_hir_item ( + decl->get_mappings ().get_crate_num (), + decl->get_mappings ().get_hirid ()) + != nullptr; + if (is_item) + { + HIR::Item *item = static_cast<HIR::Item *> (decl); + CompileItem::compile (item, ctx, true); + return true; + } + + Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx); + locals.push_back (compiled); + + return true; + }); + + return true; +} + // Mr Mangle time static const std::string kMangledSymbolPrefix = "_ZN"; |