aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2021-02-02 17:13:10 +0800
committerSimplyTheOther <simplytheother@gmail.com>2021-02-02 17:13:10 +0800
commit61b498895bcc0d99f00f0a89707d068d08e14246 (patch)
tree86a866a4467c6612ad1b8b68e6395f20aeb2daf6 /gcc/rust/backend
parent3a0c8ca2156038b726e2689e9b46be4d8c40c55f (diff)
parente0e49f434423def63312084b04ea0e60e7787e27 (diff)
downloadgcc-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.h130
-rw-r--r--gcc/rust/backend/rust-compile-expr.h152
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h67
-rw-r--r--gcc/rust/backend/rust-compile-item.h112
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc42
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.h2
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h15
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.h4
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h158
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h22
-rw-r--r--gcc/rust/backend/rust-compile.cc72
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 &param_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 &params : 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