diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-03 16:45:27 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-06 15:45:51 +0000 |
commit | 34a39466b2adb9684a1737c6ea4915e0194c26bf (patch) | |
tree | df65323e28a0b4507431969d62ac932fc2efb2d3 /gcc/rust/backend/rust-compile.cc | |
parent | 59a8fa1a80c3b2c6520c627a6bf200274732d395 (diff) | |
download | gcc-34a39466b2adb9684a1737c6ea4915e0194c26bf.zip gcc-34a39466b2adb9684a1737c6ea4915e0194c26bf.tar.gz gcc-34a39466b2adb9684a1737c6ea4915e0194c26bf.tar.bz2 |
Add in support to compile Methods and MethodCallExpr
There is more work to be done here with adjustments to the self argument
such as borrows and mutability checking.
Method resolution is basic, for now there is code to scan for all possible
matches but traits are not supported at the moment so this resolves quite
simply for now.
Fixes #191 #112
Diffstat (limited to 'gcc/rust/backend/rust-compile.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index f72cf4c..0b83c72 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -95,6 +95,83 @@ CompileExpr::visit (HIR::CallExpr &expr) } } +void +CompileExpr::visit (HIR::MethodCallExpr &expr) +{ + // lookup the resolved name + NodeId resolved_node_id = UNKNOWN_NODEID; + if (!ctx->get_resolver ()->lookup_resolved_name ( + expr.get_mappings ().get_nodeid (), &resolved_node_id)) + { + rust_error_at (expr.get_locus (), "failed to lookup resolved MethodCall"); + return; + } + + // reverse lookup + HirId ref; + 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 failure"); + return; + } + + // lookup compiled functions + Bfunction *fn = nullptr; + if (!ctx->lookup_function_decl (ref, &fn)) + { + // this might fail because its a forward decl so we can attempt to + // resolve it now + HIR::InherentImplItem *resolved_item + = ctx->get_mappings ()->lookup_hir_implitem ( + expr.get_mappings ().get_crate_num (), ref); + if (resolved_item == nullptr) + { + rust_error_at (expr.get_locus (), "failed to lookup forward decl"); + return; + } + + TyTy::TyBase *self_type = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + expr.get_receiver ()->get_mappings ().get_hirid (), &self_type)) + { + rust_error_at (expr.get_locus (), + "failed to resolve type for self param"); + return; + } + + CompileInherentImplItem::Compile (self_type, resolved_item, ctx, true); + if (!ctx->lookup_function_decl (ref, &fn)) + { + rust_error_at (expr.get_locus (), "forward decl was not compiled"); + return; + } + } + + Bexpression *fn_expr + = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ()); + + std::vector<Bexpression *> args; + + // method receiver + Bexpression *self = CompileExpr::Compile (expr.get_receiver ().get (), ctx); + rust_assert (self != nullptr); + args.push_back (self); + + // normal args + expr.iterate_params ([&] (HIR::Expr *p) mutable -> bool { + Bexpression *compiled_expr = CompileExpr::Compile (p, ctx); + rust_assert (compiled_expr != nullptr); + args.push_back (compiled_expr); + return true; + }); + + auto fncontext = ctx->peek_fn (); + translated + = ctx->get_backend ()->call_expression (fncontext.fndecl, fn_expr, args, + nullptr, expr.get_locus ()); +} + // rust-compile-block.h void |