diff options
author | SimplyTheOther <simplytheother@gmail.com> | 2021-02-02 17:13:10 +0800 |
---|---|---|
committer | SimplyTheOther <simplytheother@gmail.com> | 2021-02-02 17:13:10 +0800 |
commit | 61b498895bcc0d99f00f0a89707d068d08e14246 (patch) | |
tree | 86a866a4467c6612ad1b8b68e6395f20aeb2daf6 /gcc/rust/backend | |
parent | 3a0c8ca2156038b726e2689e9b46be4d8c40c55f (diff) | |
parent | e0e49f434423def63312084b04ea0e60e7787e27 (diff) | |
download | gcc-61b498895bcc0d99f00f0a89707d068d08e14246.zip gcc-61b498895bcc0d99f00f0a89707d068d08e14246.tar.gz gcc-61b498895bcc0d99f00f0a89707d068d08e14246.tar.bz2 |
Merge with upstream
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 130 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 152 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-fnparam.h | 67 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 112 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 42 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-stmt.h | 15 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-struct-field-expr.h | 4 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-tyty.h | 158 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-var-decl.h | 22 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 72 |
11 files changed, 529 insertions, 247 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 298ff50..034568f 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -26,6 +26,7 @@ #include "rust-backend.h" #include "rust-compile-tyty.h" #include "rust-ast-full.h" +#include "rust-hir-full.h" namespace Rust { namespace Compile { @@ -223,22 +224,109 @@ public: void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } - void visit (TyTy::UnitType &type) override { gcc_unreachable (); } - void visit (TyTy::InferType &type) override { gcc_unreachable (); } - void visit (TyTy::FnType &type) override { gcc_unreachable (); } - void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } - void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + void visit (TyTy::FnType &type) override + { + Backend::Btyped_identifier receiver; + std::vector<Backend::Btyped_identifier> parameters; + std::vector<Backend::Btyped_identifier> results; + + if (!type.get_return_type ()->is_unit ()) + { + auto hir_type = type.get_return_type (); + auto ret = TyTyResolveCompile::compile (ctx, hir_type); + results.push_back (Backend::Btyped_identifier ( + "_", ret, + ctx->get_mappings ()->lookup_location (hir_type->get_ref ()))); + } + + for (auto ¶m_pair : type.get_params ()) + { + auto param_tyty = param_pair.second; + auto compiled_param_type + = TyTyResolveCompile::compile (ctx, param_tyty); + + auto compiled_param = Backend::Btyped_identifier ( + param_pair.first->as_string (), compiled_param_type, + ctx->get_mappings ()->lookup_location (param_tyty->get_ref ())); + + parameters.push_back (compiled_param); + } + + translated = ctx->get_backend ()->function_type ( + receiver, parameters, results, NULL, + ctx->get_mappings ()->lookup_location (type.get_ref ())); + } + + void visit (TyTy::UnitType &type) override + { + translated = ctx->get_backend ()->void_type (); + } void visit (TyTy::ADTType &type) override { - ::Btype *compiled_type = nullptr; - bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); - rust_assert (ok); - translated = compiled_type; + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &translated); + if (ok) + return; + + // create implicit struct + std::vector<Backend::Btyped_identifier> fields; + for (size_t i = 0; i < type.num_fields (); i++) + { + TyTy::StructFieldType *field = type.get_field (i); + Btype *compiled_field_ty + = TyTyCompile::compile (ctx->get_backend (), + field->get_field_type ()); + + Backend::Btyped_identifier f (field->get_name (), compiled_field_ty, + ctx->get_mappings ()->lookup_location ( + type.get_ty_ref ())); + fields.push_back (std::move (f)); + } + + Btype *struct_type_record = ctx->get_backend ()->struct_type (fields); + Btype *named_struct + = ctx->get_backend ()->named_type (type.get_name (), struct_type_record, + ctx->get_mappings ()->lookup_location ( + type.get_ty_ref ())); + + ctx->push_type (named_struct); + ctx->insert_compiled_type (type.get_ty_ref (), named_struct); + translated = named_struct; + } + + void visit (TyTy::TupleType &type) override + { + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &translated); + if (ok) + return; + + // create implicit struct + std::vector<Backend::Btyped_identifier> fields; + for (size_t i = 0; i < type.num_fields (); i++) + { + TyTy::TyBase *field = type.get_field (i); + Btype *compiled_field_ty + = TyTyCompile::compile (ctx->get_backend (), field); + + Backend::Btyped_identifier f (std::to_string (i), compiled_field_ty, + ctx->get_mappings ()->lookup_location ( + type.get_ty_ref ())); + fields.push_back (std::move (f)); + } + + Btype *struct_type_record = ctx->get_backend ()->struct_type (fields); + Btype *named_struct + = ctx->get_backend ()->named_type (type.as_string (), struct_type_record, + ctx->get_mappings ()->lookup_location ( + type.get_ty_ref ())); + + ctx->push_type (named_struct); + ctx->insert_compiled_type (type.get_ty_ref (), named_struct); + translated = named_struct; } void visit (TyTy::ArrayType &type) override @@ -257,7 +345,7 @@ public: void visit (TyTy::BoolType &type) override { ::Btype *compiled_type = nullptr; - bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); rust_assert (ok); translated = compiled_type; } @@ -265,7 +353,7 @@ public: void visit (TyTy::IntType &type) override { ::Btype *compiled_type = nullptr; - bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); rust_assert (ok); translated = compiled_type; } @@ -273,7 +361,7 @@ public: void visit (TyTy::UintType &type) override { ::Btype *compiled_type = nullptr; - bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); rust_assert (ok); translated = compiled_type; } @@ -281,7 +369,23 @@ public: void visit (TyTy::FloatType &type) override { ::Btype *compiled_type = nullptr; - bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); + rust_assert (ok); + translated = compiled_type; + } + + void visit (TyTy::USizeType &type) override + { + ::Btype *compiled_type = nullptr; + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); + rust_assert (ok); + translated = compiled_type; + } + + void visit (TyTy::ISizeType &type) override + { + ::Btype *compiled_type = nullptr; + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); rust_assert (ok); translated = compiled_type; } diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 0370129..81d7786 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -38,7 +38,49 @@ public: return compiler.translated; } - virtual ~CompileExpr () {} + void visit (HIR::TupleIndexExpr &expr) + { + HIR::Expr *tuple_expr = expr.get_tuple_expr ().get (); + TupleIndex index = expr.get_tuple_index (); + + Bexpression *receiver_ref = CompileExpr::Compile (tuple_expr, ctx); + translated + = ctx->get_backend ()->struct_field_expression (receiver_ref, index, + expr.get_locus ()); + } + + void visit (HIR::TupleExpr &expr) + { + if (expr.is_unit ()) + { + translated = ctx->get_backend ()->unit_expression (); + return; + } + + TyTy::TyBase *tyty = nullptr; + if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), + &tyty)) + { + rust_fatal_error (expr.get_locus (), + "did not resolve type for this TupleExpr"); + return; + } + + Btype *tuple_type = TyTyResolveCompile::compile (ctx, tyty); + rust_assert (tuple_type != nullptr); + + // this assumes all fields are in order from type resolution + std::vector<Bexpression *> vals; + for (auto &elem : expr.get_tuple_elems ()) + { + auto e = CompileExpr::Compile (elem.get (), ctx); + vals.push_back (e); + } + + translated + = ctx->get_backend ()->constructor_expression (tuple_type, vals, + expr.get_locus ()); + } void visit (HIR::ReturnExpr &expr) { @@ -55,24 +97,7 @@ public: ctx->add_statement (s); } - void visit (HIR::CallExpr &expr) - { - Bexpression *fn = ResolvePathRef::Compile (expr.get_fnexpr (), ctx); - rust_assert (fn != nullptr); - - std::vector<Bexpression *> 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, args, - nullptr, expr.get_locus ()); - } + void visit (HIR::CallExpr &expr); void visit (HIR::IdentifierExpr &expr) { @@ -85,10 +110,6 @@ public: return; } - printf ("have ast node id %u ref %u for expr [%s]\n", - expr.get_mappings ().get_nodeid (), ref_node_id, - expr.as_string ().c_str ()); - // these ref_node_ids will resolve to a pattern declaration but we are // interested in the definition that this refers to get the parent id Resolver::Definition def; @@ -106,35 +127,45 @@ public: return; } - // this could be a constant reference - if (ctx->lookup_const_decl (ref, &translated)) - return; - - // must be an identifier + Bfunction *fn = nullptr; Bvariable *var = nullptr; - if (!ctx->lookup_var_decl (ref, &var)) + if (ctx->lookup_const_decl (ref, &translated)) { - rust_fatal_error (expr.get_locus (), - "failed to lookup compiled variable"); return; } - - translated = ctx->get_backend ()->var_expression (var, expr.get_locus ()); + else if (ctx->lookup_function_decl (ref, &fn)) + { + translated + = ctx->get_backend ()->function_code_expression (fn, + expr.get_locus ()); + } + else if (ctx->lookup_var_decl (ref, &var)) + { + translated + = ctx->get_backend ()->var_expression (var, expr.get_locus ()); + } + else + { + rust_fatal_error (expr.get_locus (), + "failed to lookup compiled reference"); + } } void visit (HIR::LiteralExpr &expr) { + auto literal_value = expr.get_literal (); switch (expr.get_lit_type ()) { case HIR::Literal::BOOL: { - bool bval = expr.as_string ().compare ("true") == 0; + bool bval = literal_value->as_string ().compare ("true") == 0; translated = ctx->get_backend ()->boolean_constant_expression (bval); } return; case HIR::Literal::INT: { mpz_t ival; - if (mpz_init_set_str (ival, expr.as_string ().c_str (), 10) != 0) + if (mpz_init_set_str (ival, literal_value->as_string ().c_str (), 10) + != 0) { rust_fatal_error (expr.get_locus (), "bad number in literal"); return; @@ -157,7 +188,7 @@ public: case HIR::Literal::FLOAT: { mpfr_t fval; - if (mpfr_init_set_str (fval, expr.as_string ().c_str (), 10, + if (mpfr_init_set_str (fval, literal_value->as_string ().c_str (), 10, MPFR_RNDN) != 0) { @@ -357,6 +388,25 @@ public: expr.get_locus ()); } + void visit (HIR::NegationExpr &expr) + { + Operator op (OPERATOR_INVALID); + switch (expr.get_negation_type ()) + { + case HIR::NegationExpr::NegationType::NEGATE: + op = OPERATOR_MINUS; + break; + + case HIR::NegationExpr::NegationType::NOT: + op = OPERATOR_NOT; + break; + } + + Bexpression *negated_expr = CompileExpr::Compile (expr.get_expr (), ctx); + translated = ctx->get_backend ()->unary_expression (op, negated_expr, + expr.get_locus ()); + } + void visit (HIR::IfExpr &expr) { auto stmt = CompileConditionalBlocks::compile (&expr, ctx); @@ -401,6 +451,36 @@ public: struct_expr.get_locus ()); } + void visit (HIR::GroupedExpr &expr) + { + translated = CompileExpr::Compile (expr.get_expr_in_parens ().get (), ctx); + } + + void visit (HIR::FieldAccessExpr &expr) + { + // resolve the receiver back to ADT type + TyTy::TyBase *receiver = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver)) + { + rust_error_at (expr.get_receiver_expr ()->get_locus_slow (), + "unresolved type for receiver"); + return; + } + rust_assert (receiver->get_kind () == TyTy::TypeKind::ADT); + + TyTy::ADTType *adt = (TyTy::ADTType *) receiver; + size_t index = 0; + adt->get_field (expr.get_field_name (), &index); + + Bexpression *struct_ref + = CompileExpr::Compile (expr.get_receiver_expr ().get (), ctx); + + translated + = ctx->get_backend ()->struct_field_expression (struct_ref, index, + expr.get_locus ()); + } + private: CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h new file mode 100644 index 0000000..cf6e6f7 --- /dev/null +++ b/gcc/rust/backend/rust-compile-fnparam.h @@ -0,0 +1,67 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_COMPILE_FNPARAM +#define RUST_COMPILE_FNPARAM + +#include "rust-compile-base.h" + +namespace Rust { +namespace Compile { + +class CompileFnParam : public HIRCompileBase +{ +public: + static Bvariable *compile (Context *ctx, Bfunction *fndecl, + HIR::FunctionParam *param, Btype *decl_type, + Location locus) + { + CompileFnParam compiler (ctx, fndecl, decl_type, locus); + param->get_param_name ()->accept_vis (compiler); + return compiler.translated; + } + + void visit (HIR::IdentifierPattern &pattern) + { + if (!pattern.is_mut) + decl_type = ctx->get_backend ()->immutable_type (decl_type); + + translated + = ctx->get_backend ()->parameter_variable (fndecl, pattern.variable_ident, + decl_type, + false /* address_taken */, + locus); + } + +private: + CompileFnParam (Context *ctx, ::Bfunction *fndecl, ::Btype *decl_type, + Location locus) + : HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type), + locus (locus), translated (nullptr) + {} + + ::Bfunction *fndecl; + ::Btype *decl_type; + Location locus; + ::Bvariable *translated; +}; + +} // namespace Compile +} // namespace Rust + +#endif // RUST_COMPILE_FNPARAM diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index c5fe9a2..1bb7c91 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -24,6 +24,7 @@ #include "rust-compile-var-decl.h" #include "rust-compile-stmt.h" #include "rust-compile-expr.h" +#include "rust-compile-fnparam.h" namespace Rust { namespace Compile { @@ -31,41 +32,38 @@ namespace Compile { class CompileItem : public HIRCompileBase { public: - static void compile (HIR::Item *item, Context *ctx) + static void compile (HIR::Item *item, Context *ctx, bool compile_fns = true) { - CompileItem compiler (ctx); + CompileItem compiler (ctx, compile_fns); item->accept_vis (compiler); } - virtual ~CompileItem () {} - - void visit (HIR::StructStruct &struct_decl) + void visit (HIR::TupleStruct &struct_decl) { - std::vector<Backend::Btyped_identifier> fields; - struct_decl.iterate ([&] (HIR::StructField &field) mutable -> bool { - TyTy::TyBase *resolved_type = nullptr; - bool ok - = ctx->get_tyctx ()->lookup_type (field.get_mappings ().get_hirid (), - &resolved_type); - rust_assert (ok); + TyTy::TyBase *resolved = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + struct_decl.get_mappings ().get_hirid (), &resolved)) + { + rust_fatal_error (struct_decl.get_locus (), + "Failed to lookup type for struct decl"); + return; + } - Btype *compiled_field_ty - = TyTyCompile::compile (ctx->get_backend (), resolved_type); + TyTyResolveCompile::compile (ctx, resolved); + } - Backend::Btyped_identifier f (field.field_name, compiled_field_ty, - field.get_locus ()); - fields.push_back (std::move (f)); - return true; - }); + void visit (HIR::StructStruct &struct_decl) + { + TyTy::TyBase *resolved = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + struct_decl.get_mappings ().get_hirid (), &resolved)) + { + rust_fatal_error (struct_decl.get_locus (), + "Failed to lookup type for struct decl"); + return; + } - Btype *struct_type_record = ctx->get_backend ()->struct_type (fields); - Btype *named_struct - = ctx->get_backend ()->named_type (struct_decl.get_identifier (), - struct_type_record, - struct_decl.get_locus ()); - ctx->push_type (named_struct); - ctx->insert_compiled_type (struct_decl.get_mappings ().get_hirid (), - named_struct); + TyTyResolveCompile::compile (ctx, resolved); } void visit (HIR::StaticItem &var) @@ -116,6 +114,9 @@ public: void visit (HIR::Function &function) { + if (!compile_fns) + return; + // items can be forward compiled which means we may not need to invoke this // code Bfunction *lookup = nullptr; @@ -127,16 +128,23 @@ public: return; } - TyTy::TyBase *fnType; + TyTy::TyBase *fntype_tyty; if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (), - &fnType)) + &fntype_tyty)) { rust_fatal_error (function.locus, "failed to lookup function type"); return; } + if (fntype_tyty->get_kind () != TyTy::TypeKind::FNDEF) + { + rust_error_at (function.get_locus (), "invalid TyTy for function item"); + return; + } + + TyTy::FnType *fntype = (TyTy::FnType *) fntype_tyty; // convert to the actual function type - auto compiled_fn_type = TyTyCompile::compile (ctx->get_backend (), fnType); + ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype); unsigned int flags = 0; bool is_main_fn = function.function_name.compare ("main") == 0; @@ -159,18 +167,34 @@ public: ctx->insert_function_decl (function.get_mappings ().get_hirid (), fndecl); // setup the params - TyTy::TyBase *tyret = TyTyExtractRetFromFnType::compile (fnType); - std::vector<TyTy::ParamType *> typarams - = TyTyExtractParamsFromFnType::compile (fnType); + + TyTy::TyBase *tyret = fntype->return_type (); std::vector<Bvariable *> param_vars; - for (auto &it : typarams) + size_t i = 0; + for (auto &it : fntype->get_params ()) { - auto compiled_param - = TyTyCompileParam::compile (ctx->get_backend (), fndecl, it); - param_vars.push_back (compiled_param); - - ctx->insert_var_decl (it->get_ref (), compiled_param); + HIR::FunctionParam &referenced_param = function.function_params.at (i); + auto param_tyty = it.second; + auto compiled_param_type + = TyTyResolveCompile::compile (ctx, param_tyty); + + Location param_locus + = ctx->get_mappings ()->lookup_location (param_tyty->get_ref ()); + Bvariable *compiled_param_var + = CompileFnParam::compile (ctx, fndecl, &referenced_param, + compiled_param_type, param_locus); + if (compiled_param_var == nullptr) + { + rust_error_at (param_locus, "failed to compile parameter variable"); + return; + } + + param_vars.push_back (compiled_param_var); + + ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (), + compiled_param_var); + i++; } if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars)) @@ -226,7 +250,7 @@ public: Bvariable *return_address = nullptr; if (function.has_function_return_type ()) { - Btype *return_type = TyTyCompile::compile (ctx->get_backend (), tyret); + Btype *return_type = TyTyResolveCompile::compile (ctx, tyret); bool address_is_taken = false; Bstatement *ret_var_stmt = nullptr; @@ -246,7 +270,7 @@ public: return true; }); - if (function_body->has_expr ()) + if (function_body->has_expr () && function_body->tail_expr_reachable ()) { // the previous passes will ensure this is a valid return // dead code elimination should remove any bad trailing expressions @@ -277,7 +301,11 @@ public: } private: - CompileItem (Context *ctx) : HIRCompileBase (ctx) {} + CompileItem (Context *ctx, bool compile_fns) + : HIRCompileBase (ctx), compile_fns (compile_fns) + {} + + bool compile_fns; }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 374f8a0..818d5cb 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -28,24 +28,43 @@ void ResolvePathRef::visit (HIR::PathInExpression &expr) { // need to look up the reference for this identifier - NodeId ref_node_id; - if (!ctx->get_resolver ()->lookup_resolved_name ( + NodeId ref_node_id = UNKNOWN_NODEID; + if (ctx->get_resolver ()->lookup_resolved_name ( expr.get_mappings ().get_nodeid (), &ref_node_id)) { - rust_fatal_error (expr.get_locus (), "failed to look up resolved name"); - return; + Resolver::Definition def; + if (!ctx->get_resolver ()->lookup_definition (ref_node_id, &def)) + { + rust_error_at (expr.get_locus (), + "unknown reference for resolved name"); + return; + } + ref_node_id = def.parent; } + // this can fail because it might be a Constructor for something + // in that case the caller should attempt ResolvePathType::Compile + if (ref_node_id == UNKNOWN_NODEID) + return; + HirId ref; if (!ctx->get_mappings ()->lookup_node_to_hir ( expr.get_mappings ().get_crate_num (), ref_node_id, &ref)) { - rust_fatal_error (expr.get_locus (), "reverse lookup failure"); + rust_error_at (expr.get_locus (), "reverse call path lookup failure"); return; } - // assumes paths are functions for now - Bfunction *fn; + // this might be a variable reference or a function reference + Bvariable *var = nullptr; + if (ctx->lookup_var_decl (ref, &var)) + { + resolved = ctx->get_backend ()->var_expression (var, expr.get_locus ()); + return; + } + + // must be a function call + Bfunction *fn = nullptr; if (!ctx->lookup_function_decl (ref, &fn)) { // this might fail because its a forward decl so we can attempt to @@ -54,14 +73,14 @@ ResolvePathRef::visit (HIR::PathInExpression &expr) expr.get_mappings ().get_crate_num (), ref); if (resolved_item == nullptr) { - rust_fatal_error (expr.get_locus (), "failed to lookup forward decl"); + rust_error_at (expr.get_locus (), "failed to lookup forward decl"); return; } CompileItem::compile (resolved_item, ctx); if (!ctx->lookup_function_decl (ref, &fn)) { - rust_fatal_error (expr.get_locus (), "forward decl was not compiled"); + rust_error_at (expr.get_locus (), "forward decl was not compiled"); return; } } @@ -78,7 +97,6 @@ ResolvePathType::visit (HIR::PathInExpression &expr) if (!ctx->get_resolver ()->lookup_resolved_type ( expr.get_mappings ().get_nodeid (), &ref_node_id)) { - rust_fatal_error (expr.get_locus (), "failed to look up resolved name"); return; } @@ -86,14 +104,14 @@ ResolvePathType::visit (HIR::PathInExpression &expr) if (!ctx->get_mappings ()->lookup_node_to_hir ( expr.get_mappings ().get_crate_num (), ref_node_id, &ref)) { - rust_fatal_error (expr.get_locus (), "reverse lookup failure"); + rust_error_at (expr.get_locus (), "reverse lookup failure"); return; } // assumes paths are functions for now if (!ctx->lookup_compiled_types (ref, &resolved)) { - rust_fatal_error (expr.get_locus (), "forward decl was not compiled"); + rust_error_at (expr.get_locus (), "forward decl was not compiled"); return; } } diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h index a5543d2..2f3cb68 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.h +++ b/gcc/rust/backend/rust-compile-resolve-path.h @@ -32,7 +32,6 @@ public: { ResolvePathRef resolver (ctx); expr->accept_vis (resolver); - rust_assert (resolver.resolved != nullptr); return resolver.resolved; } @@ -51,7 +50,6 @@ public: { ResolvePathType resolver (ctx); expr->accept_vis (resolver); - rust_assert (resolver.resolved != nullptr); return resolver.resolved; } diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h index 5f7decb..c52f605 100644 --- a/gcc/rust/backend/rust-compile-stmt.h +++ b/gcc/rust/backend/rust-compile-stmt.h @@ -71,6 +71,18 @@ public: if (!stmt.has_init_expr ()) return; + TyTy::TyBase *ty = nullptr; + if (!ctx->get_tyctx ()->lookup_type (stmt.get_mappings ().get_hirid (), + &ty)) + { + rust_fatal_error (stmt.get_locus (), "failed to lookup var decl type"); + 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,7 +91,8 @@ public: return; } - auto *init = CompileExpr::Compile (stmt.get_init_expr (), ctx); + Bexpression *init = CompileExpr::Compile (stmt.get_init_expr (), ctx); + auto fnctx = ctx->peek_fn (); auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var, init); ctx->add_statement (s); diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h index a394f7a..0a16f6a 100644 --- a/gcc/rust/backend/rust-compile-struct-field-expr.h +++ b/gcc/rust/backend/rust-compile-struct-field-expr.h @@ -38,6 +38,10 @@ public: void visit (HIR::StructExprFieldIdentifierValue &field); + void visit (HIR::StructExprFieldIndexValue &field); + + void visit (HIR::StructExprFieldIdentifier &field); + private: CompileStructExprField (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index 137b74b..2c54b17 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -26,6 +26,7 @@ #include "rust-tyty.h" #include "rust-tyty-visitor.h" #include "rust-hir-map.h" +#include "rust-hir-full.h" namespace Rust { namespace Compile { @@ -45,18 +46,21 @@ public: void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } - void visit (TyTy::UnitType &type) override { gcc_unreachable (); } - void visit (TyTy::InferType &type) override { gcc_unreachable (); } void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } - void visit (TyTy::ParamType &type) override { gcc_unreachable (); } - void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + void visit (TyTy::TupleType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } + void visit (TyTy::UnitType &type) override + { + translated = backend->void_type (); + } + void visit (TyTy::FnType &type) override { Backend::Btyped_identifier receiver; @@ -71,13 +75,14 @@ public: "_", ret, mappings->lookup_location (hir_type->get_ref ()))); } - for (size_t i = 0; i < type.num_params (); i++) + for (auto ¶ms : type.get_params ()) { - auto param_tyty = type.param_at (i); - auto compiled_param_type - = TyTyCompile::compile (backend, param_tyty->get_base_type ()); + auto param_pattern = params.first; + auto param_tyty = params.second; + auto compiled_param_type = TyTyCompile::compile (backend, param_tyty); + auto compiled_param = Backend::Btyped_identifier ( - param_tyty->get_identifier (), compiled_param_type, + param_pattern->as_string (), compiled_param_type, mappings->lookup_location (param_tyty->get_ref ())); parameters.push_back (compiled_param); @@ -185,141 +190,28 @@ public: gcc_unreachable (); } -private: - TyTyCompile (::Backend *backend) - : backend (backend), translated (nullptr), - mappings (Analysis::Mappings::get ()) - {} - - ::Backend *backend; - ::Btype *translated; - Analysis::Mappings *mappings; -}; - -class TyTyExtractParamsFromFnType : public TyTy::TyVisitor -{ -public: - static std::vector<TyTy::ParamType *> compile (TyTy::TyBase *ty) + void visit (TyTy::USizeType &type) override { - TyTyExtractParamsFromFnType compiler; - ty->accept_vis (compiler); - rust_assert (compiler.ok); - return compiler.translated; + translated = backend->named_type ( + "usize", backend->integer_type (true, backend->get_pointer_size ()), + Linemap::predeclared_location ()); } - ~TyTyExtractParamsFromFnType () {} - - void visit (TyTy::UnitType &type) override { gcc_unreachable (); } - void visit (TyTy::InferType &type) override { gcc_unreachable (); } - void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } - void visit (TyTy::ADTType &type) override { gcc_unreachable (); } - void visit (TyTy::ParamType &type) override { gcc_unreachable (); } - void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } - void visit (TyTy::BoolType &type) override { gcc_unreachable (); } - void visit (TyTy::IntType &type) override { gcc_unreachable (); } - void visit (TyTy::UintType &type) override { gcc_unreachable (); } - void visit (TyTy::FloatType &type) override { gcc_unreachable (); } - void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } - - void visit (TyTy::FnType &type) override + void visit (TyTy::ISizeType &type) override { - ok = true; - for (size_t i = 0; i < type.num_params (); i++) - { - translated.push_back (type.param_at (i)); - } + translated = backend->named_type ( + "isize", backend->integer_type (false, backend->get_pointer_size ()), + Linemap::predeclared_location ()); } private: - TyTyExtractParamsFromFnType () : ok (false) {} - - bool ok; - std::vector<TyTy::ParamType *> translated; -}; - -class TyTyExtractRetFromFnType : public TyTy::TyVisitor -{ -public: - static TyTy::TyBase *compile (TyTy::TyBase *ty) - { - TyTyExtractRetFromFnType compiler; - ty->accept_vis (compiler); - rust_assert (compiler.ok); - return compiler.translated; - } - - ~TyTyExtractRetFromFnType () {} - - void visit (TyTy::UnitType &type) override { gcc_unreachable (); } - void visit (TyTy::InferType &type) override { gcc_unreachable (); } - void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } - void visit (TyTy::ADTType &type) override { gcc_unreachable (); } - void visit (TyTy::ParamType &type) override { gcc_unreachable (); } - void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } - void visit (TyTy::BoolType &type) override { gcc_unreachable (); } - void visit (TyTy::IntType &type) override { gcc_unreachable (); } - void visit (TyTy::UintType &type) override { gcc_unreachable (); } - void visit (TyTy::FloatType &type) override { gcc_unreachable (); } - void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } - - void visit (TyTy::FnType &type) override - { - ok = true; - translated = type.get_return_type (); - } - -private: - TyTyExtractRetFromFnType () : ok (false), translated (nullptr) {} - - bool ok; - TyTy::TyBase *translated; -}; - -class TyTyCompileParam : public TyTy::TyVisitor -{ -public: - static ::Bvariable *compile (::Backend *backend, Bfunction *fndecl, - TyTy::TyBase *ty) - { - TyTyCompileParam compiler (backend, fndecl); - ty->accept_vis (compiler); - rust_assert (compiler.translated != nullptr); - return compiler.translated; - } - - ~TyTyCompileParam () {} - - void visit (TyTy::UnitType &type) override { gcc_unreachable (); } - void visit (TyTy::InferType &type) override { gcc_unreachable (); } - void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } - void visit (TyTy::ADTType &type) override { gcc_unreachable (); } - void visit (TyTy::FnType &type) override { gcc_unreachable (); } - void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } - void visit (TyTy::BoolType &type) override { gcc_unreachable (); } - void visit (TyTy::IntType &type) override { gcc_unreachable (); } - void visit (TyTy::UintType &type) override { gcc_unreachable (); } - void visit (TyTy::FloatType &type) override { gcc_unreachable (); } - void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } - - void visit (TyTy::ParamType &type) override - { - auto btype = TyTyCompile::compile (backend, type.get_base_type ()); - bool tree_addressable = false; - translated = backend->parameter_variable (fndecl, type.get_identifier (), - btype, tree_addressable, - mappings->lookup_location ( - type.get_ref ())); - } - -private: - TyTyCompileParam (::Backend *backend, ::Bfunction *fndecl) - : backend (backend), translated (nullptr), fndecl (fndecl), + TyTyCompile (::Backend *backend) + : backend (backend), translated (nullptr), mappings (Analysis::Mappings::get ()) {} ::Backend *backend; - ::Bvariable *translated; - ::Bfunction *fndecl; + ::Btype *translated; Analysis::Mappings *mappings; }; diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h index be3141a..06ea5a9 100644 --- a/gcc/rust/backend/rust-compile-var-decl.h +++ b/gcc/rust/backend/rust-compile-var-decl.h @@ -42,24 +42,36 @@ public: void visit (HIR::LetStmt &stmt) { + locus = stmt.get_locus (); TyTy::TyBase *resolved_type = nullptr; bool ok = ctx->get_tyctx ()->lookup_type (stmt.get_mappings ().get_hirid (), &resolved_type); rust_assert (ok); - ::Btype *translated_type = TyTyResolveCompile::compile (ctx, resolved_type); + translated_type = TyTyResolveCompile::compile (ctx, resolved_type); + stmt.get_pattern ()->accept_vis (*this); + } + + void visit (HIR::IdentifierPattern &pattern) + { + if (!pattern.is_mut) + translated_type = ctx->get_backend ()->immutable_type (translated_type); - translated = ctx->get_backend ()->local_variable ( - fndecl, stmt.get_pattern ()->as_string (), translated_type, - NULL /*decl_var*/, false /*address_taken*/, stmt.get_locus ()); + translated + = ctx->get_backend ()->local_variable (fndecl, pattern.variable_ident, + translated_type, NULL /*decl_var*/, + false /*address_taken*/, locus); } private: CompileVarDecl (Context *ctx, ::Bfunction *fndecl) - : HIRCompileBase (ctx), fndecl (fndecl), translated (nullptr) + : HIRCompileBase (ctx), fndecl (fndecl), translated_type (nullptr), + translated (nullptr) {} ::Bfunction *fndecl; + ::Btype *translated_type; + Location locus; ::Bvariable *translated; }; diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 3f8a962..ce6d827 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -41,8 +41,58 @@ CompileCrate::Compile (HIR::Crate &crate, Context *ctx) void CompileCrate::go () { - for (auto it = crate.items.begin (); it != crate.items.end (); it++) - CompileItem::compile (it->get (), ctx); + for (auto &item : crate.items) + CompileItem::compile (item.get (), ctx, false); + + for (auto &item : crate.items) + CompileItem::compile (item.get (), ctx, true); +} + +// rust-compile-expr.h + +void +CompileExpr::visit (HIR::CallExpr &expr) +{ + // this can be a function call or it can be a constructor for a tuple struct + Bexpression *fn = ResolvePathRef::Compile (expr.get_fnexpr (), ctx); + if (fn != nullptr) + { + std::vector<Bexpression *> 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, args, + nullptr, expr.get_locus ()); + } + else + { + Btype *type = ResolvePathType::Compile (expr.get_fnexpr (), ctx); + if (type == nullptr) + { + rust_fatal_error (expr.get_locus (), + "failed to lookup type associated with call"); + return; + } + + // this assumes all fields are in order from type resolution and if a base + // struct was specified those fields are filed via accesors + std::vector<Bexpression *> vals; + expr.iterate_params ([&] (HIR::Expr *argument) mutable -> bool { + Bexpression *e = CompileExpr::Compile (argument, ctx); + vals.push_back (e); + return true; + }); + + translated + = ctx->get_backend ()->constructor_expression (type, vals, + expr.get_locus ()); + } } // rust-compile-block.h @@ -90,7 +140,7 @@ CompileBlock::visit (HIR::BlockExpr &expr) return true; }); - if (expr.has_expr ()) + if (expr.has_expr () && expr.tail_expr_reachable ()) { // the previous passes will ensure this is a valid return // dead code elimination should remove any bad trailing expressions @@ -178,5 +228,21 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifierValue &field) translated = CompileExpr::Compile (field.get_value (), ctx); } +void +CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field) +{ + translated = CompileExpr::Compile (field.get_value (), ctx); +} + +void +CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field) +{ + // we can make the field look like an identifier expr to take advantage of + // existing code + HIR::IdentifierExpr expr (field.get_mappings (), field.get_field_name (), + field.get_locus ()); + translated = CompileExpr::Compile (&expr, ctx); +} + } // namespace Compile } // namespace Rust |