aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2020-12-15 17:48:11 +0000
committerPhilip Herron <herron.philip@googlemail.com>2020-12-17 17:23:46 +0000
commit6136f0aebbb84cbcf8f92bed206733391aaa3866 (patch)
tree49c24a3b9c9483bb2755642496bcd0aec3f8c598 /gcc
parenta621e19365473b477d121c28a057cc25d3951c76 (diff)
downloadgcc-6136f0aebbb84cbcf8f92bed206733391aaa3866.zip
gcc-6136f0aebbb84cbcf8f92bed206733391aaa3866.tar.gz
gcc-6136f0aebbb84cbcf8f92bed206733391aaa3866.tar.bz2
This is a new HIR -> GIMPLE pass it reuses the mappings from hir,
name resolution and type resolution to simplify the generation of gimple.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-base.h249
-rw-r--r--gcc/rust/backend/rust-compile-context.h247
-rw-r--r--gcc/rust/backend/rust-compile-expr.h285
-rw-r--r--gcc/rust/backend/rust-compile-item.h180
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc81
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.h52
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h85
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h247
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h69
-rw-r--r--gcc/rust/backend/rust-compile.cc19
-rw-r--r--gcc/rust/backend/rust-compile.h48
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h29
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.h2
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h11
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h23
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.h4
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h10
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h29
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h13
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h1
-rw-r--r--gcc/rust/typecheck/rust-tyctx.cc16
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h4
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc2
-rw-r--r--gcc/rust/typecheck/rust-tyty.h35
-rw-r--r--gcc/rust/util/rust-hir-map.cc66
-rw-r--r--gcc/rust/util/rust-hir-map.h14
32 files changed, 1738 insertions, 99 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 56f308e..5ac60ea 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -70,6 +70,7 @@ GRS_OBJS = \
rust/rust-ast-full-test.o \
rust/rust-session-manager.o \
rust/rust-compile.o \
+ rust/rust-compile-resolve-path.o \
rust/rust-macro-expand.o \
rust/rust-hir-full-test.o \
rust/rust-hir-map.o \
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
new file mode 100644
index 0000000..6410fd4
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -0,0 +1,249 @@
+
+
+// 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_BASE
+#define RUST_COMPILE_BASE
+
+#include "rust-compile-context.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-full.h"
+
+namespace Rust {
+namespace Compile {
+
+class HIRCompileBase : public HIR::HIRVisitor
+{
+public:
+ virtual ~HIRCompileBase () {}
+
+ // rust-ast.h
+ // virtual void visit(AttrInput& attr_input) {}
+ // virtual void visit(TokenTree& token_tree) {}
+ // virtual void visit(MacroMatch& macro_match) {}
+ virtual void visit (HIR::Token &tok) {}
+ virtual void visit (HIR::DelimTokenTree &delim_tok_tree) {}
+ virtual void visit (HIR::AttrInputMetaItemContainer &input) {}
+ // virtual void visit(MetaItem& meta_item) {}
+ // virtual void visit(Stmt& stmt) {}
+ // virtual void visit(Expr& expr) {}
+ virtual void visit (HIR::IdentifierExpr &ident_expr) {}
+ // virtual void visit(Pattern& pattern) {}
+ // virtual void visit(Type& type) {}
+ // virtual void visit(TypeParamBound& type_param_bound) {}
+ virtual void visit (HIR::Lifetime &lifetime) {}
+ // virtual void visit(GenericParam& generic_param) {}
+ virtual void visit (HIR::LifetimeParam &lifetime_param) {}
+ // virtual void visit(TraitItem& trait_item) {}
+ // virtual void visit(InherentImplItem& inherent_impl_item) {}
+ // virtual void visit(TraitImplItem& trait_impl_item) {}
+ virtual void visit (HIR::MacroInvocationSemi &macro) {}
+
+ // rust-path.h
+ virtual void visit (HIR::PathInExpression &path) {}
+ virtual void visit (HIR::TypePathSegment &segment) {}
+ virtual void visit (HIR::TypePathSegmentGeneric &segment) {}
+ virtual void visit (HIR::TypePathSegmentFunction &segment) {}
+ virtual void visit (HIR::TypePath &path) {}
+ virtual void visit (HIR::QualifiedPathInExpression &path) {}
+ virtual void visit (HIR::QualifiedPathInType &path) {}
+
+ // rust-expr.h
+ virtual void visit (HIR::LiteralExpr &expr) {}
+ virtual void visit (HIR::AttrInputLiteral &attr_input) {}
+ virtual void visit (HIR::MetaItemLitExpr &meta_item) {}
+ virtual void visit (HIR::MetaItemPathLit &meta_item) {}
+ virtual void visit (HIR::BorrowExpr &expr) {}
+ virtual void visit (HIR::DereferenceExpr &expr) {}
+ virtual void visit (HIR::ErrorPropagationExpr &expr) {}
+ virtual void visit (HIR::NegationExpr &expr) {}
+ virtual void visit (HIR::ArithmeticOrLogicalExpr &expr) {}
+ virtual void visit (HIR::ComparisonExpr &expr) {}
+ virtual void visit (HIR::LazyBooleanExpr &expr) {}
+ virtual void visit (HIR::TypeCastExpr &expr) {}
+ virtual void visit (HIR::AssignmentExpr &expr) {}
+ virtual void visit (HIR::CompoundAssignmentExpr &expr) {}
+ virtual void visit (HIR::GroupedExpr &expr) {}
+ // virtual void visit(ArrayElems& elems) {}
+ virtual void visit (HIR::ArrayElemsValues &elems) {}
+ virtual void visit (HIR::ArrayElemsCopied &elems) {}
+ virtual void visit (HIR::ArrayExpr &expr) {}
+ virtual void visit (HIR::ArrayIndexExpr &expr) {}
+ virtual void visit (HIR::TupleExpr &expr) {}
+ virtual void visit (HIR::TupleIndexExpr &expr) {}
+ virtual void visit (HIR::StructExprStruct &expr) {}
+ // virtual void visit(StructExprField& field) {}
+ virtual void visit (HIR::StructExprFieldIdentifier &field) {}
+ virtual void visit (HIR::StructExprFieldIdentifierValue &field) {}
+ virtual void visit (HIR::StructExprFieldIndexValue &field) {}
+ virtual void visit (HIR::StructExprStructFields &expr) {}
+ virtual void visit (HIR::StructExprStructBase &expr) {}
+ virtual void visit (HIR::StructExprTuple &expr) {}
+ virtual void visit (HIR::StructExprUnit &expr) {}
+ // virtual void visit(EnumExprField& field) {}
+ virtual void visit (HIR::EnumExprFieldIdentifier &field) {}
+ virtual void visit (HIR::EnumExprFieldIdentifierValue &field) {}
+ virtual void visit (HIR::EnumExprFieldIndexValue &field) {}
+ virtual void visit (HIR::EnumExprStruct &expr) {}
+ virtual void visit (HIR::EnumExprTuple &expr) {}
+ virtual void visit (HIR::EnumExprFieldless &expr) {}
+ virtual void visit (HIR::CallExpr &expr) {}
+ virtual void visit (HIR::MethodCallExpr &expr) {}
+ virtual void visit (HIR::FieldAccessExpr &expr) {}
+ virtual void visit (HIR::ClosureExprInner &expr) {}
+ virtual void visit (HIR::BlockExpr &expr) {}
+ virtual void visit (HIR::ClosureExprInnerTyped &expr) {}
+ virtual void visit (HIR::ContinueExpr &expr) {}
+ virtual void visit (HIR::BreakExpr &expr) {}
+ virtual void visit (HIR::RangeFromToExpr &expr) {}
+ virtual void visit (HIR::RangeFromExpr &expr) {}
+ virtual void visit (HIR::RangeToExpr &expr) {}
+ virtual void visit (HIR::RangeFullExpr &expr) {}
+ virtual void visit (HIR::RangeFromToInclExpr &expr) {}
+ virtual void visit (HIR::RangeToInclExpr &expr) {}
+ virtual void visit (HIR::ReturnExpr &expr) {}
+ virtual void visit (HIR::UnsafeBlockExpr &expr) {}
+ virtual void visit (HIR::LoopExpr &expr) {}
+ virtual void visit (HIR::WhileLoopExpr &expr) {}
+ virtual void visit (HIR::WhileLetLoopExpr &expr) {}
+ virtual void visit (HIR::ForLoopExpr &expr) {}
+ virtual void visit (HIR::IfExpr &expr) {}
+ virtual void visit (HIR::IfExprConseqElse &expr) {}
+ virtual void visit (HIR::IfExprConseqIf &expr) {}
+ virtual void visit (HIR::IfExprConseqIfLet &expr) {}
+ virtual void visit (HIR::IfLetExpr &expr) {}
+ virtual void visit (HIR::IfLetExprConseqElse &expr) {}
+ virtual void visit (HIR::IfLetExprConseqIf &expr) {}
+ virtual void visit (HIR::IfLetExprConseqIfLet &expr) {}
+ // virtual void visit(MatchCase& match_case) {}
+ // virtual void visit (HIR::MatchCaseBlockExpr &match_case) {}
+ // virtual void visit (HIR::MatchCaseExpr &match_case) {}
+ virtual void visit (HIR::MatchExpr &expr) {}
+ virtual void visit (HIR::AwaitExpr &expr) {}
+ virtual void visit (HIR::AsyncBlockExpr &expr) {}
+
+ // rust-item.h
+ virtual void visit (HIR::TypeParam &param) {}
+ // virtual void visit(WhereClauseItem& item) {}
+ virtual void visit (HIR::LifetimeWhereClauseItem &item) {}
+ virtual void visit (HIR::TypeBoundWhereClauseItem &item) {}
+ virtual void visit (HIR::Method &method) {}
+ virtual void visit (HIR::ModuleBodied &module) {}
+ virtual void visit (HIR::ModuleNoBody &module) {}
+ virtual void visit (HIR::ExternCrate &crate) {}
+ // virtual void visit(UseTree& use_tree) {}
+ virtual void visit (HIR::UseTreeGlob &use_tree) {}
+ virtual void visit (HIR::UseTreeList &use_tree) {}
+ virtual void visit (HIR::UseTreeRebind &use_tree) {}
+ virtual void visit (HIR::UseDeclaration &use_decl) {}
+ virtual void visit (HIR::Function &function) {}
+ virtual void visit (HIR::TypeAlias &type_alias) {}
+ virtual void visit (HIR::StructStruct &struct_item) {}
+ virtual void visit (HIR::TupleStruct &tuple_struct) {}
+ virtual void visit (HIR::EnumItem &item) {}
+ virtual void visit (HIR::EnumItemTuple &item) {}
+ virtual void visit (HIR::EnumItemStruct &item) {}
+ virtual void visit (HIR::EnumItemDiscriminant &item) {}
+ virtual void visit (HIR::Enum &enum_item) {}
+ virtual void visit (HIR::Union &union_item) {}
+ virtual void visit (HIR::ConstantItem &const_item) {}
+ virtual void visit (HIR::StaticItem &static_item) {}
+ virtual void visit (HIR::TraitItemFunc &item) {}
+ virtual void visit (HIR::TraitItemMethod &item) {}
+ virtual void visit (HIR::TraitItemConst &item) {}
+ virtual void visit (HIR::TraitItemType &item) {}
+ virtual void visit (HIR::Trait &trait) {}
+ virtual void visit (HIR::InherentImpl &impl) {}
+ virtual void visit (HIR::TraitImpl &impl) {}
+ // virtual void visit(ExternalItem& item) {}
+ virtual void visit (HIR::ExternalStaticItem &item) {}
+ virtual void visit (HIR::ExternalFunctionItem &item) {}
+ virtual void visit (HIR::ExternBlock &block) {}
+
+ // rust-macro.h
+ virtual void visit (HIR::MacroMatchFragment &match) {}
+ virtual void visit (HIR::MacroMatchRepetition &match) {}
+ virtual void visit (HIR::MacroMatcher &matcher) {}
+ virtual void visit (HIR::MacroRulesDefinition &rules_def) {}
+ virtual void visit (HIR::MacroInvocation &macro_invoc) {}
+ virtual void visit (HIR::MetaItemPath &meta_item) {}
+ virtual void visit (HIR::MetaItemSeq &meta_item) {}
+ virtual void visit (HIR::MetaWord &meta_item) {}
+ virtual void visit (HIR::MetaNameValueStr &meta_item) {}
+ virtual void visit (HIR::MetaListPaths &meta_item) {}
+ virtual void visit (HIR::MetaListNameValueStr &meta_item) {}
+
+ // rust-pattern.h
+ virtual void visit (HIR::LiteralPattern &pattern) {}
+ virtual void visit (HIR::IdentifierPattern &pattern) {}
+ virtual void visit (HIR::WildcardPattern &pattern) {}
+ // virtual void visit(RangePatternBound& bound) {}
+ virtual void visit (HIR::RangePatternBoundLiteral &bound) {}
+ virtual void visit (HIR::RangePatternBoundPath &bound) {}
+ virtual void visit (HIR::RangePatternBoundQualPath &bound) {}
+ virtual void visit (HIR::RangePattern &pattern) {}
+ virtual void visit (HIR::ReferencePattern &pattern) {}
+ // virtual void visit(StructPatternField& field) {}
+ virtual void visit (HIR::StructPatternFieldTuplePat &field) {}
+ virtual void visit (HIR::StructPatternFieldIdentPat &field) {}
+ virtual void visit (HIR::StructPatternFieldIdent &field) {}
+ virtual void visit (HIR::StructPattern &pattern) {}
+ // virtual void visit(TupleStructItems& tuple_items) {}
+ virtual void visit (HIR::TupleStructItemsNoRange &tuple_items) {}
+ virtual void visit (HIR::TupleStructItemsRange &tuple_items) {}
+ virtual void visit (HIR::TupleStructPattern &pattern) {}
+ // virtual void visit(TuplePatternItems& tuple_items) {}
+ virtual void visit (HIR::TuplePatternItemsMultiple &tuple_items) {}
+ virtual void visit (HIR::TuplePatternItemsRanged &tuple_items) {}
+ virtual void visit (HIR::TuplePattern &pattern) {}
+ virtual void visit (HIR::GroupedPattern &pattern) {}
+ virtual void visit (HIR::SlicePattern &pattern) {}
+
+ // rust-stmt.h
+ virtual void visit (HIR::EmptyStmt &stmt) {}
+ virtual void visit (HIR::LetStmt &stmt) {}
+ virtual void visit (HIR::ExprStmtWithoutBlock &stmt) {}
+ virtual void visit (HIR::ExprStmtWithBlock &stmt) {}
+
+ // rust-type.h
+ virtual void visit (HIR::TraitBound &bound) {}
+ virtual void visit (HIR::ImplTraitType &type) {}
+ virtual void visit (HIR::TraitObjectType &type) {}
+ virtual void visit (HIR::ParenthesisedType &type) {}
+ virtual void visit (HIR::ImplTraitTypeOneBound &type) {}
+ virtual void visit (HIR::TraitObjectTypeOneBound &type) {}
+ virtual void visit (HIR::TupleType &type) {}
+ virtual void visit (HIR::NeverType &type) {}
+ virtual void visit (HIR::RawPointerType &type) {}
+ virtual void visit (HIR::ReferenceType &type) {}
+ virtual void visit (HIR::ArrayType &type) {}
+ virtual void visit (HIR::SliceType &type) {}
+ virtual void visit (HIR::InferredType &type) {}
+ virtual void visit (HIR::BareFunctionType &type) {}
+
+protected:
+ HIRCompileBase (Context *ctx) : ctx (ctx) {}
+
+ Context *get_context () { return ctx; }
+
+ Context *ctx;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_BASE
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
new file mode 100644
index 0000000..f890678
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -0,0 +1,247 @@
+// 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_CONTEXT
+#define RUST_COMPILE_CONTEXT
+
+#include "rust-system.h"
+#include "rust-hir-map.h"
+#include "rust-name-resolver.h"
+#include "rust-hir-type-check.h"
+#include "rust-backend.h"
+#include "rust-compile-tyty.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Compile {
+
+struct fncontext
+{
+ ::Bfunction *fndecl;
+ ::Bvariable *ret_addr;
+};
+
+class Context
+{
+public:
+ Context (::Backend *backend)
+ : backend (backend), resolver (Resolver::Resolver::get ()),
+ tyctx (Resolver::TypeCheckContext::get ()),
+ mappings (Analysis::Mappings::get ())
+ {
+ // insert the builtins
+ auto builtins = resolver->get_builtin_types ();
+ for (auto it = builtins.begin (); it != builtins.end (); it++)
+ {
+ HirId ref;
+ rust_assert (
+ tyctx->lookup_type_by_node_id ((*it)->get_node_id (), &ref));
+
+ TyTy::TyBase *lookup;
+ rust_assert (tyctx->lookup_type (ref, &lookup));
+
+ auto compiled = TyTyCompile::compile (backend, lookup);
+ compiled_type_map[ref] = compiled;
+ }
+ }
+
+ ~Context () {}
+
+ bool lookup_compiled_types (HirId id, ::Btype **type)
+ {
+ auto it = compiled_type_map.find (id);
+ if (it == compiled_type_map.end ())
+ return false;
+
+ *type = it->second;
+ return true;
+ }
+
+ void insert_compiled_type (HirId id, ::Btype *type)
+ {
+ compiled_type_map[id] = type;
+ }
+
+ ::Backend *get_backend () { return backend; }
+ Resolver::Resolver *get_resolver () { return resolver; }
+ Resolver::TypeCheckContext *get_tyctx () { return tyctx; }
+ Analysis::Mappings *get_mappings () { return mappings; }
+
+ void push_block (Bblock *scope)
+ {
+ scope_stack.push_back (scope);
+ statements.push_back ({});
+ }
+
+ Bblock *pop_block ()
+ {
+ auto block = scope_stack.back ();
+ scope_stack.pop_back ();
+
+ auto stmts = statements.back ();
+ statements.pop_back ();
+
+ backend->block_add_statements (block, stmts);
+
+ return block;
+ }
+
+ Bblock *peek_enclosing_scope ()
+ {
+ if (scope_stack.size () == 0)
+ return nullptr;
+
+ return scope_stack.back ();
+ }
+
+ void add_statement (Bstatement *stmt) { statements.back ().push_back (stmt); }
+
+ void insert_var_decl (HirId id, ::Bvariable *decl)
+ {
+ compiled_var_decls[id] = decl;
+ }
+
+ bool lookup_var_decl (HirId id, ::Bvariable **decl)
+ {
+ auto it = compiled_var_decls.find (id);
+ if (it == compiled_var_decls.end ())
+ return false;
+
+ *decl = it->second;
+ return true;
+ }
+
+ void insert_function_decl (HirId id, ::Bfunction *fn)
+ {
+ compiled_fn_map[id] = fn;
+ }
+
+ bool lookup_function_decl (HirId id, ::Bfunction **fn)
+ {
+ auto it = compiled_fn_map.find (id);
+ if (it == compiled_fn_map.end ())
+ return false;
+
+ *fn = it->second;
+ return true;
+ }
+
+ void push_fn (::Bfunction *fn, ::Bvariable *ret_addr)
+ {
+ fn_stack.push_back (fncontext{fn, ret_addr});
+ }
+ void pop_fn () { fn_stack.pop_back (); }
+ fncontext peek_fn () { return fn_stack.back (); }
+
+ void push_type (::Btype *t) { type_decls.push_back (t); }
+ void push_var (::Bvariable *v) { var_decls.push_back (v); }
+ void push_const (::Bexpression *c) { const_decls.push_back (c); }
+ void push_function (::Bfunction *f) { func_decls.push_back (f); }
+
+ void write_to_backend ()
+ {
+ backend->write_global_definitions (type_decls, const_decls, func_decls,
+ var_decls);
+ }
+
+ bool function_completed (Bfunction *fn)
+ {
+ for (auto it = func_decls.begin (); it != func_decls.end (); it++)
+ {
+ Bfunction *i = (*it);
+ if (i == fn)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+private:
+ ::Backend *backend;
+ Resolver::Resolver *resolver;
+ Resolver::TypeCheckContext *tyctx;
+ Analysis::Mappings *mappings;
+
+ // state
+ std::vector<fncontext> fn_stack;
+ std::map<HirId, ::Bvariable *> compiled_var_decls;
+ std::map<HirId, ::Btype *> compiled_type_map;
+ std::map<HirId, ::Bfunction *> compiled_fn_map;
+ std::vector< ::std::vector<Bstatement *> > statements;
+ std::vector< ::Bblock *> scope_stack;
+
+ // To GCC middle-end
+ std::vector< ::Btype *> type_decls;
+ std::vector< ::Bvariable *> var_decls;
+ std::vector< ::Bexpression *> const_decls;
+ std::vector< ::Bfunction *> func_decls;
+};
+
+class TyTyResolveCompile : public TyTy::TyVisitor
+{
+public:
+ static ::Btype *compile (Context *ctx, TyTy::TyBase *ty)
+ {
+ TyTyResolveCompile compiler (ctx);
+ ty->accept_vis (compiler);
+ return compiler.translated;
+ }
+
+ virtual ~TyTyResolveCompile () {}
+
+ void visit (TyTy::FnType &type) { gcc_unreachable (); }
+
+ void visit (TyTy::BoolType &type)
+ {
+ ::Btype *compiled_type = nullptr;
+ bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type);
+ rust_assert (ok);
+ translated = compiled_type;
+ }
+
+ void visit (TyTy::IntType &type)
+ {
+ printf ("type [%s] has ref: %u\n", type.as_string ().c_str (),
+ type.get_ref ());
+
+ ::Btype *compiled_type = nullptr;
+ bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type);
+ rust_assert (ok);
+ translated = compiled_type;
+ }
+
+ void visit (TyTy::UintType &type)
+ {
+ ::Btype *compiled_type = nullptr;
+ bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type);
+ rust_assert (ok);
+ translated = compiled_type;
+ }
+
+private:
+ TyTyResolveCompile (Context *ctx) : ctx (ctx) {}
+
+ Context *ctx;
+ ::Btype *translated;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_CONTEXT
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
new file mode 100644
index 0000000..7808af2
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -0,0 +1,285 @@
+// 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_EXPR
+#define RUST_COMPILE_EXPR
+
+#include "rust-compile-base.h"
+#include "rust-compile-tyty.h"
+#include "rust-compile-resolve-path.h"
+
+namespace Rust {
+namespace Compile {
+
+class CompileExpr : public HIRCompileBase
+{
+public:
+ static Bexpression *Compile (HIR::Expr *expr, Context *ctx)
+ {
+ CompileExpr compiler (ctx);
+ expr->accept_vis (compiler);
+ return compiler.translated;
+ }
+
+ virtual ~CompileExpr () {}
+
+ void visit (HIR::ReturnExpr &expr)
+ {
+ Bexpression *compiled_expr
+ = CompileExpr::Compile (expr.return_expr.get (), ctx);
+ rust_assert (compiled_expr != nullptr);
+
+ auto fncontext = ctx->peek_fn ();
+
+ std::vector<Bexpression *> retstmts;
+ retstmts.push_back (compiled_expr);
+ auto s = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts,
+ expr.get_locus ());
+ ctx->add_statement (s);
+ }
+
+ void visit (HIR::CallExpr &expr)
+ {
+ Bexpression *fn = ResolvePath::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::IdentifierExpr &expr)
+ {
+ // need to look up the reference for this identifier
+ NodeId ref_node_id;
+ 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;
+ }
+
+ 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;
+ if (!ctx->get_resolver ()->lookup_definition (ref_node_id, &def))
+ {
+ rust_error_at (expr.get_locus (), "unknown reference");
+ return;
+ }
+
+ HirId ref;
+ if (!ctx->get_mappings ()->lookup_node_to_hir (
+ expr.get_mappings ().get_crate_num (), def.parent, &ref))
+ {
+ rust_fatal_error (expr.get_locus (), "reverse lookup failure");
+ return;
+ }
+
+ Bvariable *var = nullptr;
+ if (!ctx->lookup_var_decl (ref, &var))
+ {
+ rust_fatal_error (expr.get_locus (),
+ "failed to lookup compiled variable");
+ return;
+ }
+
+ translated = ctx->get_backend ()->var_expression (var, expr.get_locus ());
+ }
+
+ void visit (HIR::LiteralExpr &expr)
+ {
+ switch (expr.get_lit_type ())
+ {
+ case HIR::Literal::BOOL: {
+ bool bval = expr.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)
+ {
+ rust_fatal_error (expr.get_locus (), "bad number in literal");
+ 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 literal expr");
+ return;
+ }
+
+ Btype *type = TyTyResolveCompile::compile (ctx, tyty);
+ translated
+ = ctx->get_backend ()->integer_constant_expression (type, ival);
+ }
+ return;
+
+ default:
+ rust_fatal_error (expr.get_locus (), "unknown literal");
+ return;
+ }
+
+ gcc_unreachable ();
+ }
+
+ void visit (HIR::AssignmentExpr &expr)
+ {
+ fncontext fn = ctx->peek_fn ();
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ Bstatement *assignment
+ = ctx->get_backend ()->assignment_statement (fn.fndecl, lhs, rhs,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
+
+ void visit (HIR::ArithmeticOrLogicalExpr &expr)
+ {
+ Operator op;
+ switch (expr.get_expr_type ())
+ {
+ case HIR::ArithmeticOrLogicalExpr::ADD:
+ op = OPERATOR_PLUS;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::SUBTRACT:
+ op = OPERATOR_MINUS;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::MULTIPLY:
+ op = OPERATOR_MULT;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::DIVIDE:
+ op = OPERATOR_DIV;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::MODULUS:
+ op = OPERATOR_MOD;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_AND:
+ op = OPERATOR_AND;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_OR:
+ op = OPERATOR_OR;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_XOR:
+ op = OPERATOR_XOR;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::LEFT_SHIFT:
+ op = OPERATOR_LSHIFT;
+ break;
+ case HIR::ArithmeticOrLogicalExpr::RIGHT_SHIFT:
+ op = OPERATOR_RSHIFT;
+ break;
+ default:
+ rust_fatal_error (expr.get_locus (), "failed to compile operator");
+ return;
+ }
+
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ translated = ctx->get_backend ()->binary_expression (op, lhs, rhs,
+ expr.get_locus ());
+ }
+
+ void visit (HIR::ComparisonExpr &expr)
+ {
+ Operator op;
+ switch (expr.get_expr_type ())
+ {
+ case HIR::ComparisonExpr::EQUAL:
+ op = OPERATOR_EQEQ;
+ break;
+ case HIR::ComparisonExpr::NOT_EQUAL:
+ op = OPERATOR_NOTEQ;
+ break;
+ case HIR::ComparisonExpr::GREATER_THAN:
+ op = OPERATOR_GT;
+ break;
+ case HIR::ComparisonExpr::LESS_THAN:
+ op = OPERATOR_LT;
+ break;
+ case HIR::ComparisonExpr::GREATER_OR_EQUAL:
+ op = OPERATOR_GE;
+ break;
+ case HIR::ComparisonExpr::LESS_OR_EQUAL:
+ op = OPERATOR_LE;
+ break;
+ default:
+ rust_fatal_error (expr.get_locus (), "failed to compile operator");
+ return;
+ }
+
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ translated = ctx->get_backend ()->binary_expression (op, lhs, rhs,
+ expr.get_locus ());
+ }
+
+ void visit (HIR::LazyBooleanExpr &expr)
+ {
+ Operator op;
+ switch (expr.get_expr_type ())
+ {
+ case HIR::LazyBooleanExpr::LOGICAL_OR:
+ op = OPERATOR_OROR;
+ break;
+ case HIR::LazyBooleanExpr::LOGICAL_AND:
+ op = OPERATOR_ANDAND;
+ break;
+ default:
+ rust_fatal_error (expr.get_locus (), "failed to compile operator");
+ return;
+ }
+
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ translated = ctx->get_backend ()->binary_expression (op, lhs, rhs,
+ expr.get_locus ());
+ }
+
+private:
+ CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
+
+ Bexpression *translated;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_EXPR
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
new file mode 100644
index 0000000..dd07435
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -0,0 +1,180 @@
+// 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_ITEM
+#define RUST_COMPILE_ITEM
+
+#include "rust-compile-base.h"
+#include "rust-compile-tyty.h"
+#include "rust-compile-var-decl.h"
+#include "rust-compile-stmt.h"
+
+namespace Rust {
+namespace Compile {
+
+class CompileItem : public HIRCompileBase
+{
+public:
+ static void compile (HIR::Item *item, Context *ctx)
+ {
+ CompileItem compiler (ctx);
+ item->accept_vis (compiler);
+ }
+
+ virtual ~CompileItem () {}
+
+ void visit (HIR::Function &function)
+ {
+ // items can be forward compiled which means we may not need to invoke this
+ // code
+ Bfunction *lookup = nullptr;
+ if (ctx->lookup_function_decl (function.get_mappings ().get_hirid (),
+ &lookup))
+ {
+ // has this been added to the list then it must be finished
+ if (ctx->function_completed (lookup))
+ {
+ printf ("returning early the function [%s] is completed!\n",
+ function.as_string ().c_str ());
+ return;
+ }
+ }
+
+ TyTy::TyBase *fnType;
+ if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
+ &fnType))
+ {
+ rust_fatal_error (function.locus, "failed to lookup function type");
+ return;
+ }
+
+ // convert to the actual function type
+ auto compiled_fn_type = TyTyCompile::compile (ctx->get_backend (), fnType);
+
+ Bfunction *fndecl
+ = ctx->get_backend ()->function (compiled_fn_type, function.function_name,
+ "" /* asm_name */, 0 /* flags */,
+ function.get_locus ());
+ 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);
+ std::vector<Bvariable *> param_vars;
+
+ for (auto &it : typarams)
+ {
+ 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);
+ }
+
+ if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+ {
+ rust_fatal_error (function.get_locus (),
+ "failed to setup parameter variables");
+ return;
+ }
+
+ // lookup locals
+ auto block_expr = function.function_body.get ();
+ auto body_mappings = block_expr->get_mappings ();
+
+ Resolver::Rib *rib = nullptr;
+ if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
+ &rib))
+ {
+ rust_fatal_error (function.get_locus (),
+ "failed to setup locals per block");
+ return;
+ }
+
+ std::vector<Bvariable *> locals;
+ rib->iterate_decls ([&] (NodeId n) 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;
+ });
+
+ Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
+ HIR::BlockExpr *function_body = function.function_body.get ();
+
+ Location start_location = function_body->get_locus ();
+ Location end_location = function_body->get_closing_locus ();
+
+ Bblock *code_block
+ = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+ start_location, end_location);
+ ctx->push_block (code_block);
+
+ Bvariable *return_address = nullptr;
+ if (function.has_function_return_type ())
+ {
+ Btype *return_type = TyTyCompile::compile (ctx->get_backend (), tyret);
+
+ bool address_is_taken = false;
+ Bstatement *ret_var_stmt = nullptr;
+
+ return_address = ctx->get_backend ()->temporary_variable (
+ fndecl, code_block, return_type, NULL, address_is_taken,
+ function.get_locus (), &ret_var_stmt);
+
+ ctx->add_statement (ret_var_stmt);
+ }
+
+ ctx->push_fn (fndecl, return_address);
+
+ // compile the block
+ function_body->iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
+ CompileStmt::Compile (s, ctx);
+ return true;
+ });
+
+ ctx->pop_block ();
+ auto body = ctx->get_backend ()->block_statement (code_block);
+ if (!ctx->get_backend ()->function_set_body (fndecl, body))
+ {
+ rust_error_at (function.get_locus (), "failed to set body to function");
+ return;
+ }
+
+ ctx->pop_fn ();
+
+ ctx->push_function (fndecl);
+ }
+
+private:
+ CompileItem (Context *ctx) : HIRCompileBase (ctx) {}
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_ITEM
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
new file mode 100644
index 0000000..e6683fa
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -0,0 +1,81 @@
+// 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/>.
+
+#include "rust-linemap.h"
+#include "rust-backend.h"
+#include "rust-compile-resolve-path.h"
+#include "rust-compile-item.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+ResolvePath::visit (HIR::PathInExpression &expr)
+{
+ // need to look up the reference for this identifier
+ NodeId ref_node_id;
+ 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;
+ }
+
+ printf ("PATHIN have ast node id %u ref %u for expr [%s]\n",
+ expr.get_mappings ().get_nodeid (), ref_node_id,
+ expr.as_string ().c_str ());
+
+ 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");
+ return;
+ }
+
+ // assumes paths are functions for now
+ Bfunction *fn;
+ if (!ctx->lookup_function_decl (ref, &fn))
+ {
+ printf (
+ "path failed to lookup function attempting to forward resolve!\n");
+
+ // this might fail because its a forward decl so we can attempt to
+ // resolve it now
+ HIR::Item *resolved_item = ctx->get_mappings ()->lookup_hir_item (
+ expr.get_mappings ().get_crate_num (), ref);
+ if (resolved_item == nullptr)
+ {
+ rust_fatal_error (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");
+ return;
+ }
+ }
+
+ resolved
+ = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ());
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h
new file mode 100644
index 0000000..d8f393d
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-resolve-path.h
@@ -0,0 +1,52 @@
+// 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_RESOLVE_PATH
+#define RUST_COMPILE_RESOLVE_PATH
+
+#include "rust-compile-base.h"
+#include "rust-compile-tyty.h"
+
+namespace Rust {
+namespace Compile {
+
+class ResolvePath : public HIRCompileBase
+{
+public:
+ static Bexpression *Compile (HIR::Expr *expr, Context *ctx)
+ {
+ ResolvePath resolver (ctx);
+ expr->accept_vis (resolver);
+ rust_assert (resolver.resolved != nullptr);
+ return resolver.resolved;
+ }
+
+ virtual ~ResolvePath () {}
+
+ void visit (HIR::PathInExpression &expr);
+
+private:
+ ResolvePath (Context *ctx) : HIRCompileBase (ctx), resolved (nullptr) {}
+
+ Bexpression *resolved;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_RESOLVE_PATH
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
new file mode 100644
index 0000000..0a08130
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -0,0 +1,85 @@
+// 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_STMT
+#define RUST_COMPILE_STMT
+
+#include "rust-compile-base.h"
+#include "rust-compile-tyty.h"
+#include "rust-compile-expr.h"
+
+namespace Rust {
+namespace Compile {
+
+class CompileStmt : public HIRCompileBase
+{
+public:
+ static void Compile (HIR::Stmt *stmt, Context *ctx)
+ {
+ CompileStmt compiler (ctx);
+ stmt->accept_vis (compiler);
+ rust_assert (compiler.ok);
+ }
+
+ virtual ~CompileStmt () {}
+
+ void visit (HIR::ExprStmtWithoutBlock &stmt)
+ {
+ ok = true;
+ auto translated = CompileExpr::Compile (stmt.get_expr (), ctx);
+
+ // these can be null
+ if (translated == nullptr)
+ return;
+
+ gcc_unreachable ();
+ }
+
+ void visit (HIR::LetStmt &stmt)
+ {
+ // marks that the statement has been looked at
+ ok = true;
+
+ // nothing to do
+ if (!stmt.has_init_expr ())
+ return;
+
+ Bvariable *var = nullptr;
+ if (!ctx->lookup_var_decl (stmt.get_mappings ().get_hirid (), &var))
+ {
+ rust_fatal_error (stmt.get_locus (),
+ "failed to lookup compiled variable decl");
+ return;
+ }
+
+ auto *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);
+ }
+
+private:
+ CompileStmt (Context *ctx) : HIRCompileBase (ctx), ok (false) {}
+
+ bool ok;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_STMT
diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h
new file mode 100644
index 0000000..66d2472
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -0,0 +1,247 @@
+// 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_TYTY
+#define RUST_COMPILE_TYTY
+
+#include "rust-system.h"
+#include "rust-location.h"
+#include "rust-diagnostics.h"
+#include "rust-backend.h"
+#include "rust-tyty.h"
+#include "rust-tyty-visitor.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Compile {
+
+class TyTyCompile : public TyTy::TyVisitor
+{
+public:
+ static ::Btype *compile (::Backend *backend, TyTy::TyBase *ty)
+ {
+ TyTyCompile compiler (backend);
+ ty->accept_vis (compiler);
+ rust_assert (compiler.translated != nullptr);
+ return compiler.translated;
+ }
+
+ ~TyTyCompile () {}
+
+ void visit (TyTy::InferType &type) override
+ {
+ // there shouldn't be any of these left
+ gcc_unreachable ();
+ }
+
+ void visit (TyTy::UnitType &type) override {}
+
+ 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 = TyTyCompile::compile (backend, hir_type);
+ results.push_back (Backend::Btyped_identifier (
+ "_", ret, mappings->lookup_location (hir_type->get_ref ())));
+ }
+
+ for (size_t i = 0; i < type.num_params (); i++)
+ {
+ auto param_tyty = type.param_at (i);
+ auto compiled_param_type
+ = TyTyCompile::compile (backend, param_tyty->get_base_type ());
+ auto compiled_param = Backend::Btyped_identifier (
+ param_tyty->get_identifier (), compiled_param_type,
+ mappings->lookup_location (param_tyty->get_ref ()));
+
+ parameters.push_back (compiled_param);
+ }
+
+ translated
+ = backend->function_type (receiver, parameters, results, NULL,
+ mappings->lookup_location (type.get_ref ()));
+ }
+
+ void visit (TyTy::ParamType &type) override {}
+
+ void visit (TyTy::BoolType &type) override
+ {
+ translated = backend->named_type ("bool", backend->bool_type (),
+ Linemap::predeclared_location ());
+ }
+
+ void visit (TyTy::IntType &type) override
+ {
+ switch (type.get_kind ())
+ {
+ case TyTy::IntType::I8:
+ translated
+ = backend->named_type ("i8", backend->integer_type (false, 8),
+ Linemap::predeclared_location ());
+ return;
+
+ case TyTy::IntType::I16:
+ translated
+ = backend->named_type ("i16", backend->integer_type (false, 16),
+ Linemap::predeclared_location ());
+ return;
+
+ case TyTy::IntType::I32:
+ translated
+ = backend->named_type ("i32", backend->integer_type (false, 32),
+ Linemap::predeclared_location ());
+ return;
+ }
+ gcc_unreachable ();
+ }
+
+ void visit (TyTy::UintType &type) override
+ {
+ switch (type.get_kind ())
+ {
+ case TyTy::UintType::U8:
+ translated = backend->named_type ("i8", backend->integer_type (true, 8),
+ Linemap::predeclared_location ());
+ return;
+
+ case TyTy::UintType::U16:
+ translated
+ = backend->named_type ("i16", backend->integer_type (true, 16),
+ Linemap::predeclared_location ());
+ return;
+
+ case TyTy::UintType::U32:
+ translated
+ = backend->named_type ("i32", backend->integer_type (true, 32),
+ Linemap::predeclared_location ());
+ return;
+ }
+ 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)
+ {
+ TyTyExtractParamsFromFnType compiler;
+ ty->accept_vis (compiler);
+ rust_assert (compiler.ok);
+ return compiler.translated;
+ }
+
+ ~TyTyExtractParamsFromFnType () {}
+
+ void visit (TyTy::FnType &type) override
+ {
+ ok = true;
+ for (size_t i = 0; i < type.num_params (); i++)
+ {
+ translated.push_back (type.param_at (i));
+ }
+ }
+
+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::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::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),
+ mappings (Analysis::Mappings::get ())
+ {}
+
+ ::Backend *backend;
+ ::Bvariable *translated;
+ ::Bfunction *fndecl;
+ Analysis::Mappings *mappings;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_TYTY
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
new file mode 100644
index 0000000..be3141a
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -0,0 +1,69 @@
+// 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_VAR_DECL
+#define RUST_COMPILE_VAR_DECL
+
+#include "rust-compile-base.h"
+
+namespace Rust {
+namespace Compile {
+
+class CompileVarDecl : public HIRCompileBase
+{
+public:
+ static ::Bvariable *compile (::Bfunction *fndecl, HIR::Stmt *stmt,
+ Context *ctx)
+ {
+ CompileVarDecl compiler (ctx, fndecl);
+ stmt->accept_vis (compiler);
+ rust_assert (compiler.translated != nullptr);
+ ctx->insert_var_decl (stmt->get_mappings ().get_hirid (),
+ compiler.translated);
+ return compiler.translated;
+ }
+
+ virtual ~CompileVarDecl () {}
+
+ void visit (HIR::LetStmt &stmt)
+ {
+ 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 = ctx->get_backend ()->local_variable (
+ fndecl, stmt.get_pattern ()->as_string (), translated_type,
+ NULL /*decl_var*/, false /*address_taken*/, stmt.get_locus ());
+ }
+
+private:
+ CompileVarDecl (Context *ctx, ::Bfunction *fndecl)
+ : HIRCompileBase (ctx), fndecl (fndecl), translated (nullptr)
+ {}
+
+ ::Bfunction *fndecl;
+ ::Bvariable *translated;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_VAR_DECL
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index a4b5cd4..11c380b 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -17,16 +17,31 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile.h"
-#include "rust-diagnostics.h"
+#include "rust-compile-item.h"
namespace Rust {
namespace Compile {
+CompileCrate::CompileCrate (HIR::Crate &crate, Context *ctx)
+ : crate (crate), ctx (ctx)
+{}
+
CompileCrate::~CompileCrate () {}
void
CompileCrate::Compile (HIR::Crate &crate, Context *ctx)
-{}
+
+{
+ CompileCrate c (crate, ctx);
+ c.go ();
+}
+
+void
+CompileCrate::go ()
+{
+ for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+ CompileItem::compile (it->get (), ctx);
+}
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile.h b/gcc/rust/backend/rust-compile.h
index 5ee1122..18f3e54 100644
--- a/gcc/rust/backend/rust-compile.h
+++ b/gcc/rust/backend/rust-compile.h
@@ -20,55 +20,12 @@
#define RUST_COMPILE_H
#include "rust-system.h"
-#include "rust-hir-map.h"
-#include "rust-name-resolver.h"
-#include "rust-hir-type-check.h"
-#include "rust-linemap.h"
-#include "rust-backend.h"
+#include "rust-hir-full.h"
+#include "rust-compile-context.h"
namespace Rust {
namespace Compile {
-class Context
-{
-public:
- Context (::Backend *backend)
- : backend (backend), resolver (Resolver::Resolver::get ()),
- tyctx (Resolver::TypeCheckContext::get ()),
- mappings (Analysis::Mappings::get ())
- {}
-
- ~Context () {}
-
- ::Backend *get_backend () { return backend; }
- Resolver::Resolver *get_resolver () { return resolver; }
- Resolver::TypeCheckContext *get_tyctx () { return tyctx; }
- Analysis::Mappings *get_mappings () { return mappings; }
-
- void push_type (::Btype *t) { type_decls.push_back (t); }
- void push_var (::Bvariable *v) { var_decls.push_back (v); }
- void push_const (::Bexpression *c) { const_decls.push_back (c); }
- void push_function (::Bfunction *f) { func_decls.push_back (f); }
-
- void write_to_backend ()
- {
- backend->write_global_definitions (type_decls, const_decls, func_decls,
- var_decls);
- }
-
-private:
- ::Backend *backend;
- Resolver::Resolver *resolver;
- Resolver::TypeCheckContext *tyctx;
- Analysis::Mappings *mappings;
-
- // To GCC middle-end
- std::vector< ::Btype *> type_decls;
- std::vector< ::Bvariable *> var_decls;
- std::vector< ::Bexpression *> const_decls;
- std::vector< ::Bfunction *> func_decls;
-};
-
class CompileCrate
{
public:
@@ -78,6 +35,7 @@ public:
private:
CompileCrate (HIR::Crate &crate, Context *ctx);
+ void go ();
HIR::Crate &crate;
Context *ctx;
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index e0ce862..e6c86b8 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -69,9 +69,16 @@ public:
auto translated_type = std::unique_ptr<HIR::Type> (
ASTLoweringType::translate (param.get_type ().get ()));
- function_params.push_back (
- HIR::FunctionParam (std::move (translated_pattern),
- std::move (translated_type), param.get_locus ()));
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ auto hir_param
+ = HIR::FunctionParam (mapping, std::move (translated_pattern),
+ std::move (translated_type),
+ param.get_locus ());
+ function_params.push_back (hir_param);
}
std::unique_ptr<HIR::BlockExpr> function_body
@@ -83,7 +90,7 @@ public:
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
- translated
+ auto fn
= new HIR::Function (mapping, std::move (function_name),
std::move (qualifiers), std::move (generic_params),
std::move (function_params), std::move (return_type),
@@ -92,9 +99,21 @@ public:
mappings->insert_defid_mapping (mapping.get_defid (), translated);
mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
- translated);
+ fn);
mappings->insert_location (crate_num, mapping.get_hirid (),
function.get_locus ());
+
+ // add the mappings for the function params at the end
+ for (auto &param : fn->function_params)
+ {
+ mappings->insert_hir_param (mapping.get_crate_num (),
+ param.get_mappings ()->get_hirid (),
+ &param);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ param.get_locus ());
+ }
+
+ translated = fn;
}
// Helpers
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h
index c813639..c57d14f 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.h
+++ b/gcc/rust/hir/rust-ast-lower-stmt.h
@@ -60,6 +60,7 @@ public:
stmt.get_locus ());
mappings->insert_location (crate_num, mapping.get_hirid (),
stmt.get_locus ());
+ mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated);
}
void visit (AST::LetStmt &stmt)
@@ -86,6 +87,7 @@ public:
std::move (outer_attrs), stmt.get_locus ());
mappings->insert_location (crate_num, mapping.get_hirid (),
stmt.get_locus ());
+ mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated);
}
private:
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index b08aa91..36c2085 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -536,6 +536,7 @@ public:
void accept_vis (HIRVisitor &vis) override;
Expr *get_lhs () { return main_or_left_expr.get (); }
+ Expr *get_rhs () { return right_expr.get (); }
/* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
* maybe? */
@@ -610,6 +611,8 @@ public:
Expr *get_lhs () { return main_or_left_expr.get (); }
+ Expr *get_rhs () { return right_expr.get (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2562,6 +2565,14 @@ public:
}
}
+ Location get_closing_locus ()
+ {
+ if (statements.size () == 0)
+ return get_locus ();
+
+ return statements[statements.size () - 1]->get_locus_slow ();
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index cf24bae..e0477f4 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -409,17 +409,20 @@ public:
std::unique_ptr<Type> type;
Location locus;
+ Analysis::NodeMapping mappings;
- FunctionParam (std::unique_ptr<Pattern> param_name,
+ FunctionParam (Analysis::NodeMapping mappings,
+ std::unique_ptr<Pattern> param_name,
std::unique_ptr<Type> param_type, Location locus)
: param_name (std::move (param_name)), type (std::move (param_type)),
- locus (locus)
+ locus (locus), mappings (mappings)
{}
// Copy constructor uses clone
FunctionParam (FunctionParam const &other)
: param_name (other.param_name->clone_pattern ()),
- type (other.type->clone_type ()), locus (other.locus)
+ type (other.type->clone_type ()), locus (other.locus),
+ mappings (other.mappings)
{}
// Overload assignment operator to use clone
@@ -428,6 +431,7 @@ public:
param_name = other.param_name->clone_pattern ();
type = other.type->clone_type ();
locus = other.locus;
+ mappings = other.mappings;
return *this;
}
@@ -436,15 +440,6 @@ public:
FunctionParam (FunctionParam &&other) = default;
FunctionParam &operator= (FunctionParam &&other) = default;
- // Returns whether FunctionParam is in an invalid state.
- bool is_error () const { return param_name == nullptr || type == nullptr; }
-
- // Creates an error FunctionParam.
- static FunctionParam create_error ()
- {
- return FunctionParam (nullptr, nullptr, Location ());
- }
-
std::string as_string () const;
Location get_locus () const { return locus; }
@@ -452,6 +447,8 @@ public:
Pattern *get_param_name () { return param_name.get (); }
Type *get_type () { return type.get (); }
+
+ Analysis::NodeMapping *get_mappings () { return &mappings; }
};
// Visibility of item - if the item has it, then it is some form of public
@@ -1191,8 +1188,6 @@ public:
Location locus;
- std::vector<LetStmt *> locals;
-
std::string as_string () const override;
// Returns whether function has generic parameters.
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index 31d55b6..c799b5e 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -117,6 +117,8 @@ public:
HIR::Expr *get_init_expr () { return init_expr.get (); }
+ HIR::Pattern *get_pattern () { return variables_pattern.get (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -174,6 +176,8 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ Expr *get_expr () { return expr.get (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index b9e7f6a..9e98fda 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -38,7 +38,13 @@ public:
void visit (AST::PathInExpression &expr)
{
- if (resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node))
+ if (!resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node))
+ {
+ rust_error_at (expr.get_locus (), "unknown path %s",
+ expr.as_string ().c_str ());
+ return;
+ }
+ else
{
resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
resolver->insert_new_definition (expr.get_node_id (),
@@ -60,7 +66,7 @@ public:
ResolveExpr::go (p, expr.get_node_id ());
return true;
});
- /// resolver->insert_resolved_name(NodeId refId,NodeId defId)
+ // resolver->insert_resolved_name(NodeId refId,NodeId defId)
}
void visit (AST::AssignmentExpr &expr)
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index a393d31..fc2da70 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -78,7 +78,6 @@ public:
void visit (AST::IdentifierPattern &pattern)
{
- printf ("declaration for: %s\n", pattern.as_string ().c_str ());
// if we have a duplicate id this then allows for shadowing correctly
// as new refs to this decl will match back here so it is ok to overwrite
resolver->get_name_scope ().insert (pattern.get_ident (),
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 623fbd4..20d40f1 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -39,6 +39,11 @@ public:
~ResolveStmt () {}
+ void visit (AST::ExprStmtWithoutBlock &stmt)
+ {
+ ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ());
+ }
+
void visit (AST::LetStmt &stmt)
{
PatternDeclaration::go (stmt.get_pattern ().get (), stmt.get_node_id ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 2e715e9..32a5d8b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -110,16 +110,25 @@ public:
return;
}
+ // 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
+ Definition def;
+ if (!resolver->lookup_definition (ref_node_id, &def))
+ {
+ rust_error_at (expr.get_locus (), "unknown reference");
+ return;
+ }
+
// node back to HIR
HirId ref;
if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref))
+ def.parent, &ref))
{
rust_error_at (expr.get_locus (), "reverse lookup failure");
return;
}
- // check if this has a type
+ // the base reference for this name _must_ have a type set
TyTy::TyBase *lookup;
if (!context->lookup_type (ref, &lookup))
{
@@ -138,13 +147,19 @@ public:
{
switch (expr.get_lit_type ())
{
- case HIR::Literal::LitType::INT:
- infered = new TyTy::IntType (expr.get_mappings ().get_hirid (),
- TyTy::IntType::IntKind::I32);
+ case HIR::Literal::LitType::INT: {
+ // FIXME:
+ // assume i32 let the combiner functions figure it out
+ // this should look at the suffix of the literal value to check
+ auto ok = context->lookup_builtin ("i32", &infered);
+ rust_assert (ok);
+ }
break;
- case HIR::Literal::LitType::BOOL:
- infered = new TyTy::BoolType (expr.get_mappings ().get_hirid ());
+ case HIR::Literal::LitType::BOOL: {
+ auto ok = context->lookup_builtin ("bool", &infered);
+ rust_assert (ok);
+ }
break;
default:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 29d6db6..ab964a9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -66,6 +66,7 @@ public:
rust_error_at (function.locus, "failed to lookup function type");
return;
}
+
// need to get the return type from this
ResolveFnType resolve_fn_type (fnType);
context->push_return_type (resolve_fn_type.go ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 39c48f0..ccf1138 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -36,6 +36,11 @@ public:
stmt->accept_vis (resolver);
}
+ void visit (HIR::ExprStmtWithoutBlock &stmt)
+ {
+ TypeCheckExpr::Resolve (stmt.get_expr ());
+ }
+
void visit (HIR::LetStmt &stmt)
{
TyTy::TyBase *init_expr_ty = nullptr;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index c15aaef..25e6c0b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -44,9 +44,18 @@ public:
else
ret_type = TypeCheckType::Resolve (function.return_type.get ());
- std::vector<TyTy::TyBase *> params;
+ std::vector<TyTy::ParamType *> params;
for (auto &param : function.function_params)
- params.push_back (TypeCheckType::Resolve (param.type.get ()));
+ {
+ // get the name as well required for later on
+ auto param_type = TypeCheckType::Resolve (param.type.get ());
+ auto param_tyty
+ = new TyTy::ParamType (param.get_mappings ()->get_hirid (),
+ param.param_name->as_string (), param_type);
+ params.push_back (param_tyty);
+
+ context->insert_type (param.get_mappings ()->get_hirid (), param_tyty);
+ }
auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
params, ret_type);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index d8721a3..beab77a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -55,6 +55,7 @@ public:
return;
}
+ // reverse lookup the hir node from ast node id
HirId hir_lookup;
if (context->lookup_type_by_node_id (ref, &hir_lookup))
{
@@ -63,7 +64,7 @@ public:
return;
}
- // this might be a struct type reference
+ // this might be a struct type (TyTy::ADT) reference
// TODO
printf ("UNREACHABLE %s\n", path.as_string ().c_str ());
gcc_unreachable ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 5a8abe1..6deecdd 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -33,6 +33,7 @@ public:
~TypeCheckContext ();
+ bool lookup_builtin (std::string name, TyTy::TyBase **type);
void insert_builtin (HirId id, NodeId ref, TyTy::TyBase *type);
void insert_type (HirId id, TyTy::TyBase *type);
diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc
index 195291e..8869e34 100644
--- a/gcc/rust/typecheck/rust-tyctx.cc
+++ b/gcc/rust/typecheck/rust-tyctx.cc
@@ -35,11 +35,23 @@ TypeCheckContext::TypeCheckContext () {}
TypeCheckContext::~TypeCheckContext () {}
+bool
+TypeCheckContext::lookup_builtin (std::string name, TyTy::TyBase **type)
+{
+ for (auto &builtin : builtins)
+ {
+ if (name.compare (builtin->as_string ()) == 0)
+ {
+ *type = builtin.get ();
+ return true;
+ }
+ }
+ return false;
+}
+
void
TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::TyBase *type)
{
- printf ("inserting builtin: hir %u node %u -> %s\n", id, ref,
- type->as_string ().c_str ());
node_id_refs[ref] = id;
resolved[id] = type;
builtins.push_back (std::unique_ptr<TyTy::TyBase> (type));
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 375d909..372229b 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -155,8 +155,8 @@ public:
TyBase *combine (TyBase *other)
{
- other->accept_vis (*this);
- return resolved;
+ // we only case about the base type of a param
+ return base->get_base_type ()->combine (other);
}
private:
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 2124408..4a36d4f 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -99,7 +99,7 @@ ParamType::accept_vis (TyVisitor &vis)
std::string
ParamType::as_string () const
{
- return "(" + type->as_string () + ")";
+ return "(" + identifier + " :" + type->as_string () + ")";
}
TyBase *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 688643c..4e04490 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -54,12 +54,12 @@ public:
virtual void accept_vis (TyVisitor &vis) = 0;
- virtual bool is_unit () const { return false; }
-
virtual std::string as_string () const = 0;
virtual TyBase *combine (TyBase *other) = 0;
+ virtual bool is_unit () const { return kind == TypeKind::UNIT; }
+
protected:
TyBase (HirId ref, TypeKind kind) : kind (kind), ref (ref) {}
@@ -95,46 +95,51 @@ public:
TyBase *combine (TyBase *other) override;
};
-class FnType : public TyBase
+class ParamType : public TyBase
{
public:
- FnType (HirId ref, std::vector<TyBase *> params, TyBase *type)
- : TyBase (ref, TypeKind::FNDEF), params (params), type (type)
+ ParamType (HirId ref, std::string identifier, TyBase *type)
+ : TyBase (ref, TypeKind::PARAM), identifier (identifier), type (type)
{}
void accept_vis (TyVisitor &vis) override;
std::string as_string () const override;
- TyBase *return_type () { return type; }
-
TyBase *combine (TyBase *other) override;
- size_t num_params () const { return params.size (); }
+ std::string get_identifier () const { return identifier; }
- TyBase *param_at (size_t idx) { return params[idx]; }
-
- TyBase *get_return_type () { return type; }
+ TyBase *get_base_type () { return type; }
private:
- std::vector<TyBase *> params;
+ std::string identifier;
TyBase *type;
};
-class ParamType : public TyBase
+class FnType : public TyBase
{
public:
- ParamType (HirId ref, TyBase *type)
- : TyBase (ref, TypeKind::PARAM), type (type)
+ FnType (HirId ref, std::vector<ParamType *> params, TyBase *type)
+ : TyBase (ref, TypeKind::FNDEF), params (params), type (type)
{}
void accept_vis (TyVisitor &vis) override;
std::string as_string () const override;
+ TyBase *return_type () { return type; }
+
TyBase *combine (TyBase *other) override;
+ size_t num_params () const { return params.size (); }
+
+ ParamType *param_at (size_t idx) { return params[idx]; }
+
+ TyBase *get_return_type () { return type; }
+
private:
+ std::vector<ParamType *> params;
TyBase *type;
};
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 70c59f3..bdf487e 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -305,6 +305,55 @@ Mappings::lookup_hir_type (CrateNum crateNum, HirId id)
}
void
+Mappings::insert_hir_stmt (CrateNum crateNum, HirId id, HIR::Stmt *type)
+{
+ rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
+
+ hirStmtMappings[crateNum][id] = type;
+ nodeIdToHirMappings[crateNum][type->get_mappings ().get_nodeid ()] = id;
+}
+
+HIR::Stmt *
+Mappings::lookup_hir_stmt (CrateNum crateNum, HirId id)
+{
+ auto it = hirStmtMappings.find (crateNum);
+ if (it == hirStmtMappings.end ())
+ return nullptr;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return nullptr;
+
+ return iy->second;
+}
+
+void
+Mappings::insert_hir_param (CrateNum crateNum, HirId id,
+ HIR::FunctionParam *param)
+{
+ rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
+
+ printf ("inserting param with node id %u hir id: %u\n",
+ param->get_mappings ()->get_nodeid (), id);
+ hirParamMappings[crateNum][id] = param;
+ nodeIdToHirMappings[crateNum][param->get_mappings ()->get_nodeid ()] = id;
+}
+
+HIR::FunctionParam *
+Mappings::lookup_hir_param (CrateNum crateNum, HirId id)
+{
+ auto it = hirParamMappings.find (crateNum);
+ if (it == hirParamMappings.end ())
+ return nullptr;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return nullptr;
+
+ return iy->second;
+}
+
+void
Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
HIR::Item *item)
{
@@ -377,5 +426,22 @@ Mappings::lookup_location (CrateNum crate, HirId id)
return iy->second;
}
+bool
+Mappings::resolve_nodeid_to_stmt (CrateNum crate, NodeId id, HIR::Stmt **stmt)
+{
+ auto it = nodeIdToHirMappings.find (crate);
+ if (it == nodeIdToHirMappings.end ())
+ return false;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return false;
+
+ HirId resolved = iy->second;
+ auto resolved_stmt = lookup_hir_stmt (crate, resolved);
+ *stmt = resolved_stmt;
+ return resolved_stmt != nullptr;
+}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 7fc8777..a400265 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -115,6 +115,12 @@ public:
void insert_hir_type (CrateNum crateNum, HirId id, HIR::Type *type);
HIR::Type *lookup_hir_type (CrateNum crateNum, HirId id);
+ void insert_hir_stmt (CrateNum crateNum, HirId id, HIR::Stmt *type);
+ HIR::Stmt *lookup_hir_stmt (CrateNum crateNum, HirId id);
+
+ void insert_hir_param (CrateNum crateNum, HirId id, HIR::FunctionParam *type);
+ HIR::FunctionParam *lookup_hir_param (CrateNum crateNum, HirId id);
+
void walk_local_defids_for_crate (CrateNum crateNum,
std::function<bool (HIR::Item *)> cb);
@@ -127,6 +133,12 @@ public:
return lookup_location (get_current_crate (), id);
}
+ bool resolve_nodeid_to_stmt (CrateNum crate, NodeId id, HIR::Stmt **stmt);
+ bool resolve_nodeid_to_stmt (NodeId id, HIR::Stmt **stmt)
+ {
+ return resolve_nodeid_to_stmt (get_current_crate (), id, stmt);
+ }
+
private:
Mappings ();
@@ -145,6 +157,8 @@ private:
std::map<CrateNum, std::map<HirId, HIR::Item *> > hirItemMappings;
std::map<CrateNum, std::map<HirId, HIR::Type *> > hirTypeMappings;
std::map<CrateNum, std::map<HirId, HIR::Expr *> > hirExprMappings;
+ std::map<CrateNum, std::map<HirId, HIR::Stmt *> > hirStmtMappings;
+ std::map<CrateNum, std::map<HirId, HIR::FunctionParam *> > hirParamMappings;
// location info
std::map<CrateNum, std::map<NodeId, Location> > locations;