diff options
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 249 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 247 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 285 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 180 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 81 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.h | 52 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-stmt.h | 85 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-tyty.h | 247 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-var-decl.h | 69 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 1506 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.h | 272 |
11 files changed, 1552 insertions, 1721 deletions
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 ¯o) {} + + // 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 ¶m) {} + // 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 ¯o_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 300240f..11c380b 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -1,1501 +1,47 @@ -#include "rust-compile.h" -#include "rust-diagnostics.h" - -namespace Rust { -namespace Compile { - -#define VISIT_POP(L, S, R, B) \ - do \ - { \ - auto before = B.size (); \ - S->accept_vis (*this); \ - if (B.size () <= before) \ - break; \ - R = B.back (); \ - B.pop_back (); \ - } \ - while (0) - -Compilation::Compilation (AST::Crate &crate, ::Backend *backend) - : crate (crate), backend (backend), scope (backend) -{} - -Compilation::~Compilation () {} - -bool -Compilation::Compile (AST::Crate &crate, ::Backend *backend) -{ - Compilation resolver (crate, backend); - return resolver.go (); -} - -bool -Compilation::go () -{ - scope.Push (); - - // builtin primitives - scope.InsertType ("bool", - backend->named_type ("bool", backend->bool_type (), - Linemap::predeclared_location ())); - scope.InsertType ("i64", - backend->named_type ("i64", - backend->integer_type (false, 64), - Linemap::predeclared_location ())); - scope.InsertType ("i32", - backend->named_type ("i32", - backend->integer_type (false, 32), - Linemap::predeclared_location ())); - scope.InsertType ("i16", - backend->named_type ("i16", - backend->integer_type (false, 16), - Linemap::predeclared_location ())); - scope.InsertType ("i8", - backend->named_type ("i8", backend->integer_type (false, 8), - Linemap::predeclared_location ())); - scope.InsertType ("u64", - backend->named_type ("u64", - backend->integer_type (true, 64), - Linemap::predeclared_location ())); - scope.InsertType ("u32", - backend->named_type ("u32", - backend->integer_type (true, 32), - Linemap::predeclared_location ())); - scope.InsertType ("u16", - backend->named_type ("u16", - backend->integer_type (true, 16), - Linemap::predeclared_location ())); - scope.InsertType ("u8", - backend->named_type ("u8", backend->integer_type (true, 8), - Linemap::predeclared_location ())); - scope.InsertType ("f64", backend->float_type (64)); - scope.InsertType ("f32", backend->float_type (32)); - - for (auto &item : crate.items) - item->accept_vis (*this); - scope.Pop (); - - // Define all globally declared values. - if (saw_errors ()) - return false; - - backend->write_global_definitions (type_decls, const_decls, func_decls, - var_decls); - return true; -} - -bool -Compilation::compileVarDecl (Bfunction *fndecl, AST::LetStmt *stmt, - std::vector<Bvariable *> &vars) -{ - AST::Type *type = stmt->has_type () ? stmt->get_type ().get () : stmt->inferedType; - translatedType = NULL; - type->accept_vis (*this); - if (translatedType == NULL) - { - rust_error_at (stmt->get_locus (), "failed to compile type for var decl"); - return false; - } - - stmt->get_pattern ()->accept_vis (*this); - for (auto &pattern : patternBuffer) - { - auto var = backend->local_variable (fndecl, pattern.get_ident (), - translatedType, NULL /*decl_var*/, - false /*address_taken*/, stmt->get_locus ()); - vars.push_back (var); - scope.InsertVar (pattern.get_ident (), var); - } - patternBuffer.clear (); - return true; -} - -Bexpression * -Compilation::compileBooleanLiteral (std::string val) -{ - bool bval = val.compare ("true") == 0; - return backend->boolean_constant_expression (bval); -} - -Bexpression * -Compilation::compileFloatLiteral (std::string val, Location locus) -{ - Btype *type = NULL; - bool ok = scope.LookupType ("f32", &type); - if (!ok) - { - rust_fatal_error (locus, "unable to find type"); - return NULL; - } - mpfr_t fval; - if (mpfr_init_set_str (fval, val.c_str (), 10, GMP_RNDN) != 0) - { - rust_fatal_error (locus, "bad number in literal"); - return NULL; - } - return backend->float_constant_expression (type, fval); -} - -Bexpression * -Compilation::compileIntegerLiteral (std::string val, Location locus) -{ - Btype *type = NULL; - bool ok = scope.LookupType ("i32", &type); - if (!ok) - { - rust_fatal_error (locus, "unable to find type"); - return NULL; - } - mpz_t ival; - if (mpz_init_set_str (ival, val.c_str (), 10) != 0) - { - rust_fatal_error (locus, "bad number in literal"); - return NULL; - } - return backend->integer_constant_expression (type, ival); -} - -void -Compilation::visit (AST::Token &tok) -{} - -void -Compilation::visit (AST::DelimTokenTree &delim_tok_tree) -{} - -void -Compilation::visit (AST::AttrInputMetaItemContainer &input) -{} - -void -Compilation::visit (AST::IdentifierExpr &ident_expr) -{ - Bvariable *var = NULL; - if (!scope.LookupVar (ident_expr.as_string (), &var)) - { - rust_fatal_error (ident_expr.get_locus (), "unknown var"); - return; - } - exprs.push_back (backend->var_expression (var, ident_expr.get_locus ())); -} - -void -Compilation::visit (AST::Lifetime &lifetime) -{} - -void -Compilation::visit (AST::LifetimeParam &lifetime_param) -{} - -void -Compilation::visit (AST::MacroInvocationSemi ¯o) -{} - -// rust-path.h -void -Compilation::visit (AST::PathInExpression &path) -{ - Bfunction *fn = NULL; - if (scope.LookupFunction (path.as_string (), &fn)) - { - auto expr - = backend->function_code_expression (fn, path.get_locus ()); - exprs.push_back (expr); - translatedType = scope.GetFnRetType (fn); - return; - } -} - -void -Compilation::visit (AST::TypePathSegment &segment) -{} -void -Compilation::visit (AST::TypePathSegmentGeneric &segment) -{} -void -Compilation::visit (AST::TypePathSegmentFunction &segment) -{} - -void -Compilation::visit (AST::TypePath &path) -{ - if (path.get_segments ().size () > 1) - { - rust_error_at (path.get_locus (), "unable to compile multi segment types yet"); - return; - } - - Btype *type = NULL; - if (!scope.LookupType (path.as_string (), &type)) - { - rust_error_at (path.get_locus (), "unknown type"); - return; - } - translatedType = type; -} - -void -Compilation::visit (AST::QualifiedPathInExpression &path) -{} -void -Compilation::visit (AST::QualifiedPathInType &path) -{} - -// rust-expr.h -void -Compilation::visit (AST::LiteralExpr &expr) -{ - Bexpression *compiled; - switch (expr.get_lit_type ()) - { - case AST::Literal::BOOL: - compiled = compileBooleanLiteral (expr.as_string ()); - break; - - case AST::Literal::FLOAT: - compiled - = compileFloatLiteral (expr.as_string (), expr.get_locus ()); - break; - - case AST::Literal::INT: - compiled - = compileIntegerLiteral (expr.as_string (), expr.get_locus ()); - break; - - default: - rust_fatal_error (expr.get_locus (), "unknown literal"); - return; - } - - exprs.push_back (compiled); -} - -void -Compilation::visit (AST::AttrInputLiteral &attr_input) -{} -void -Compilation::visit (AST::MetaItemLitExpr &meta_item) -{} -void -Compilation::visit (AST::MetaItemPathLit &meta_item) -{} -void -Compilation::visit (AST::BorrowExpr &expr) -{} -void -Compilation::visit (AST::DereferenceExpr &expr) -{} -void -Compilation::visit (AST::ErrorPropagationExpr &expr) -{} - -void -Compilation::visit (AST::NegationExpr &expr) -{ - Bexpression *root = NULL; - VISIT_POP (expr.get_negated_expr ()->get_locus_slow (), expr.get_negated_expr ().get (), root, - exprs); - if (root == NULL) - { - rust_error_at (expr.get_negated_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Operator op; - switch (expr.get_negation_type ()) - { - case AST::NegationExpr::NEGATE: - op = OPERATOR_MINUS; - break; - case AST::NegationExpr::NOT: - op = OPERATOR_NOT; - break; - default: - rust_fatal_error (expr.get_locus (), "failed to compile operator"); - return; - } - - auto unary = backend->unary_expression (op, root, expr.get_locus ()); - exprs.push_back (unary); -} - -void -Compilation::visit (AST::ArithmeticOrLogicalExpr &expr) -{ - Bexpression *lhs = NULL; - VISIT_POP (expr.get_left_expr ()->get_locus_slow (), expr.get_left_expr ().get (), lhs, exprs); - if (lhs == NULL) - { - rust_error_at (expr.get_left_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Bexpression *rhs = NULL; - VISIT_POP (expr.get_right_expr ()->get_locus_slow (), expr.get_right_expr ().get (), rhs, exprs); - if (rhs == NULL) - { - rust_error_at (expr.get_right_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Operator op; - switch (expr.get_expr_type ()) - { - case AST::ArithmeticOrLogicalExpr::ADD: - op = OPERATOR_PLUS; - break; - case AST::ArithmeticOrLogicalExpr::SUBTRACT: - op = OPERATOR_MINUS; - break; - case AST::ArithmeticOrLogicalExpr::MULTIPLY: - op = OPERATOR_MULT; - break; - case AST::ArithmeticOrLogicalExpr::DIVIDE: - op = OPERATOR_DIV; - break; - case AST::ArithmeticOrLogicalExpr::MODULUS: - op = OPERATOR_MOD; - break; - case AST::ArithmeticOrLogicalExpr::BITWISE_AND: - op = OPERATOR_AND; - break; - case AST::ArithmeticOrLogicalExpr::BITWISE_OR: - op = OPERATOR_OR; - break; - case AST::ArithmeticOrLogicalExpr::BITWISE_XOR: - op = OPERATOR_XOR; - break; - case AST::ArithmeticOrLogicalExpr::LEFT_SHIFT: - op = OPERATOR_LSHIFT; - break; - case AST::ArithmeticOrLogicalExpr::RIGHT_SHIFT: - op = OPERATOR_RSHIFT; - break; - default: - rust_fatal_error (expr.get_locus (), "failed to compile operator"); - return; - } - - auto binExpr - = backend->binary_expression (op, lhs, rhs, expr.get_locus ()); - exprs.push_back (binExpr); -} - -void -Compilation::visit (AST::ComparisonExpr &expr) -{ - Bexpression *lhs = NULL; - VISIT_POP (expr.get_left_expr ()->get_locus_slow (), expr.get_left_expr ().get (), lhs, exprs); - if (lhs == NULL) - { - rust_error_at (expr.get_left_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Bexpression *rhs = NULL; - VISIT_POP (expr.get_right_expr ()->get_locus_slow (), expr.get_right_expr ().get (), rhs, exprs); - if (rhs == NULL) - { - rust_error_at (expr.get_right_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Operator op; - switch (expr.get_expr_type ()) - { - case AST::ComparisonExpr::EQUAL: - op = OPERATOR_EQEQ; - break; - case AST::ComparisonExpr::NOT_EQUAL: - op = OPERATOR_NOTEQ; - break; - case AST::ComparisonExpr::GREATER_THAN: - op = OPERATOR_GT; - break; - case AST::ComparisonExpr::LESS_THAN: - op = OPERATOR_LT; - break; - case AST::ComparisonExpr::GREATER_OR_EQUAL: - op = OPERATOR_GE; - break; - case AST::ComparisonExpr::LESS_OR_EQUAL: - op = OPERATOR_LE; - break; - default: - rust_fatal_error (expr.get_locus (), "failed to compile operator"); - return; - } - - auto compExpr - = backend->binary_expression (op, lhs, rhs, expr.get_locus ()); - exprs.push_back (compExpr); -} - -void -Compilation::visit (AST::LazyBooleanExpr &expr) -{ - Bexpression *lhs = NULL; - VISIT_POP (expr.get_left_expr ()->get_locus_slow (), expr.get_left_expr ().get (), lhs, exprs); - if (lhs == NULL) - { - rust_error_at (expr.get_left_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Bexpression *rhs = NULL; - VISIT_POP (expr.get_right_expr ()->get_locus_slow (), expr.get_right_expr ().get (), rhs, exprs); - if (rhs == NULL) - { - rust_error_at (expr.get_right_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Operator op; - switch (expr.get_expr_type ()) - { - case AST::LazyBooleanExpr::LOGICAL_OR: - op = OPERATOR_OROR; - break; - case AST::LazyBooleanExpr::LOGICAL_AND: - op = OPERATOR_ANDAND; - break; - default: - rust_fatal_error (expr.get_locus (), "failed to compile operator"); - return; - } - - auto compExpr - = backend->binary_expression (op, lhs, rhs, expr.get_locus ()); - exprs.push_back (compExpr); -} - -void -Compilation::visit (AST::TypeCastExpr &expr) -{} - -void -Compilation::visit (AST::AssignmentExpr &expr) -{ - Bexpression *lhs = NULL; - VISIT_POP (expr.get_left_expr ()->get_locus_slow (), expr.get_left_expr ().get (), lhs, exprs); - if (lhs == NULL) - { - rust_error_at (expr.get_left_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - Bexpression *rhs = NULL; - VISIT_POP (expr.get_right_expr ()->get_locus_slow (), expr.get_right_expr ().get (), rhs, exprs); - if (rhs == NULL) - { - rust_error_at (expr.get_right_expr ()->get_locus_slow (), "failed to compile"); - return; - } - - auto s = backend->assignment_statement (scope.GetCurrentFndecl (), lhs, rhs, - expr.get_locus ()); - scope.AddStatement (s); -} - -void -Compilation::visit (AST::CompoundAssignmentExpr &expr) -{} -void -Compilation::visit (AST::GroupedExpr &expr) -{} - -void -Compilation::visit (AST::ArrayElemsValues &elems) -{ - std::vector< ::Bexpression *> elements; - - bool failed = false; - elems.iterate ([&] (AST::Expr *expr) mutable -> bool { - Bexpression *value = nullptr; - VISIT_POP (expr.get_locus_slow (), expr, value, exprs); - if (value == nullptr) - { - rust_fatal_error (expr->get_locus_slow (), - "failed to compile value to array initialiser"); - return false; - } - elements.push_back (value); - return true; - }); - - // nothing to do when its failed - if (failed) - return; - - arrayConsStack.push_back (elements); -} - -void -Compilation::visit (AST::ArrayElemsCopied &elems) -{} - -void -Compilation::visit (AST::ArrayExpr &expr) -{ - translatedType = nullptr; - expr.get_inferred_type ()->accept_vis (*this); - if (translatedType == nullptr) - { - rust_error_at (expr.get_locus_slow (), - "failed to compile array type for ArrayExpr"); - return; - } - - ::Btype *compiledType = translatedType; - translatedType = nullptr; - - auto before = arrayConsStack.size (); - expr.get_array_elems ()->accept_vis (*this); - if (arrayConsStack.size () <= before) - { - rust_error_at (expr.get_locus_slow (), - "failed to compile the array constructor"); - return; - } - std::vector< ::Bexpression *> initializer = arrayConsStack.back (); - arrayConsStack.pop_back (); - - std::vector<unsigned long> indexes; - for (unsigned long i = 0; i < initializer.size (); ++i) - indexes.push_back (i); - - Bexpression *cons - = backend->array_constructor_expression (compiledType, indexes, initializer, - expr.get_locus_slow ()); - exprs.push_back (cons); -} - -void -Compilation::visit (AST::ArrayIndexExpr &expr) -{ - Bexpression *arrayExpr = nullptr; - VISIT_POP (expr.get_array_expr ()->get_locus_slow (), expr.get_array_expr (), - arrayExpr, exprs); - if (arrayExpr == nullptr) - { - rust_error_at (expr.get_locus_slow (), - "failed to compile value to array expression reference"); - return; - } - - Bexpression *indexExpr = nullptr; - VISIT_POP (expr.get_index_expr ()->get_locus_slow (), expr.get_index_expr (), - indexExpr, exprs); - if (indexExpr == nullptr) - { - rust_error_at (expr.get_locus_slow (), - "failed to compile value to array index expression"); - return; - } - - Bexpression *indexExpression - = backend->array_index_expression (arrayExpr, indexExpr, - expr.get_locus_slow ()); - exprs.push_back (indexExpression); -} - -void -Compilation::visit (AST::TupleExpr &expr) -{} -void -Compilation::visit (AST::TupleIndexExpr &expr) -{} -void -Compilation::visit (AST::StructExprStruct &expr) -{} -// void Compilation::visit(StructExprField& field) {} -void -Compilation::visit (AST::StructExprFieldIdentifier &field) -{} - -void -Compilation::visit (AST::StructExprFieldIdentifierValue &field) -{ - Bexpression *value = NULL; - VISIT_POP (field.get_value ()->get_locus_slow (), field.get_value ().get (), value, exprs); - if (value == NULL) - { - rust_fatal_error (field.get_value ()->get_locus_slow (), - "failed to compile value to struct"); - return; - } - exprs.push_back (value); -} - -void -Compilation::visit (AST::StructExprFieldIndexValue &field) -{ - Bexpression *value = NULL; - VISIT_POP (field.get_value ()->get_locus_slow (), field.get_value ().get (), value, exprs); - if (value == NULL) - { - rust_fatal_error (field.get_value ()->get_locus_slow (), - "failed to compile value to struct"); - return; - } - exprs.push_back (value); -} - -void -Compilation::visit (AST::StructExprStructFields &expr) -{ - AST::StructStruct *decl = NULL; - if (!scope.LookupStructDecl (expr.get_struct_name ().as_string (), &decl)) - { - rust_error_at (expr.get_locus (), "unknown type"); - return; - } - - Btype *structType = NULL; - if (!scope.LookupType (expr.get_struct_name ().as_string (), &structType)) - { - rust_fatal_error (expr.get_locus (), "unknown type"); - return; - } - - structBuffer.push_back (decl); - std::vector<Bexpression *> constructor; - - // FIXME type resolution pass should ensures these are in correct order - // and have defaults if required - for (auto &field : expr.get_fields ()) - { - Bexpression *value = NULL; - VISIT_POP (expr.get_locus (), field, value, exprs); - if (value == NULL) - { - rust_fatal_error (expr.get_locus (), - "failed to compile value to struct"); - return; - } - - constructor.push_back (value); - } - - structBuffer.pop_back (); - auto cons = backend->constructor_expression (structType, constructor, - expr.get_locus ()); - exprs.push_back (cons); -} - -void -Compilation::visit (AST::StructExprStructBase &expr) -{} -void -Compilation::visit (AST::StructExprTuple &expr) -{} -void -Compilation::visit (AST::StructExprUnit &expr) -{} -// void Compilation::visit(EnumExprField& field) {} -void -Compilation::visit (AST::EnumExprFieldIdentifier &field) -{} -void -Compilation::visit (AST::EnumExprFieldIdentifierValue &field) -{} -void -Compilation::visit (AST::EnumExprFieldIndexValue &field) -{} -void -Compilation::visit (AST::EnumExprStruct &expr) -{} -void -Compilation::visit (AST::EnumExprTuple &expr) -{} -void -Compilation::visit (AST::EnumExprFieldless &expr) -{} - -void -Compilation::visit (AST::CallExpr &expr) -{ - Bexpression *fn = NULL; - VISIT_POP (expr.get_function_expr ()->get_locus_slow (), expr.get_function_expr (), fn, exprs); - if (fn == NULL) - { - rust_error_at (expr.get_function_expr ()->get_locus_slow (), "failed to resolve"); - return; - } - - std::vector<Bexpression *> args; - for (auto ¶m : expr.get_params ()) - { - Bexpression *arg = NULL; - VISIT_POP (param->get_locus_slow (), param, arg, exprs); - if (arg == NULL) - { - rust_error_at (param->get_locus_slow (), - "failed to compile argument"); - return; - } - - args.push_back (arg); - } - - auto call = backend->call_expression (scope.GetCurrentFndecl (), fn, args, - NULL, expr.get_locus ()); - exprs.push_back (call); -} - -void -Compilation::visit (AST::MethodCallExpr &expr) -{} -void -Compilation::visit (AST::FieldAccessExpr &expr) -{} -void -Compilation::visit (AST::ClosureExprInner &expr) -{} - -void -Compilation::visit (AST::BlockExpr &expr) -{ - Bblock *enclosingScope = NULL; - Location start_location; /* = stmt.locus; FIXME */ - Location end_location; // FIXME - - std::vector<Bvariable *> vars; - auto code_block - = backend->block (scope.GetCurrentFndecl (), scope.CurBlock (), vars, - start_location, end_location); - - scope.PushBlock (code_block); - for (auto &stmt : expr.get_statements ()) - { - stmt->accept_vis (*this); - } - // dont pop -} - -void -Compilation::visit (AST::ClosureExprInnerTyped &expr) -{} -void -Compilation::visit (AST::ContinueExpr &expr) -{} -void -Compilation::visit (AST::BreakExpr &expr) -{} -void -Compilation::visit (AST::RangeFromToExpr &expr) -{} -void -Compilation::visit (AST::RangeFromExpr &expr) -{} -void -Compilation::visit (AST::RangeToExpr &expr) -{} -void -Compilation::visit (AST::RangeFullExpr &expr) -{} -void -Compilation::visit (AST::RangeFromToInclExpr &expr) -{} -void -Compilation::visit (AST::RangeToInclExpr &expr) -{} - -void -Compilation::visit (AST::ReturnExpr &expr) -{ - Bexpression *ret = NULL; - VISIT_POP (expr.get_returned_expr ()->get_locus_slow (), expr.get_returned_expr ().get (), ret, exprs); - if (ret == NULL) - { - rust_fatal_error (expr.get_returned_expr ()->get_locus_slow (), - "failed to compile"); - return; - } - - std::vector<Bexpression *> retstmts; - retstmts.push_back (ret); - auto s = backend->return_statement (scope.GetCurrentFndecl (), retstmts, - expr.get_locus ()); - scope.AddStatement (s); -} - -void -Compilation::visit (AST::UnsafeBlockExpr &expr) -{} - -void -Compilation::visit (AST::LoopExpr &expr) -{} - -void -Compilation::visit (AST::WhileLoopExpr &expr) -{} - -void -Compilation::visit (AST::WhileLetLoopExpr &expr) -{} -void -Compilation::visit (AST::ForLoopExpr &expr) -{} - -void -Compilation::visit (AST::IfExpr &expr) -{ - Bexpression *cond = NULL; - VISIT_POP (expr.get_condition_expr ()->get_locus_slow (), - expr.get_condition_expr ().get (), cond, exprs); - if (cond == NULL) - { - rust_error_at (expr.get_condition_expr ()->get_locus_slow (), - "failed to compile"); - return; - } - - expr.vis_if_block (*this); - Bblock *then_block = scope.PopBlock (); - - auto stmt = backend->if_statement (scope.GetCurrentFndecl (), cond, - then_block, NULL, expr.get_locus ()); - stmts.push_back (stmt); -} - -void -Compilation::visit (AST::IfExprConseqElse &expr) -{ - Bexpression *cond = NULL; - VISIT_POP (expr.get_condition_expr ()->get_locus_slow (), - expr.get_condition_expr ().get (), cond, exprs); - if (cond == NULL) - { - rust_error_at (expr.get_condition_expr ()->get_locus_slow (), - "failed to compile"); - return; - } - - expr.vis_if_block (*this); - Bblock *then_block = scope.PopBlock (); - - expr.vis_else_block (*this); - Bblock *else_block = scope.PopBlock (); - - auto stmt - = backend->if_statement (scope.GetCurrentFndecl (), cond, then_block, - else_block, expr.get_locus ()); - stmts.push_back (stmt); -} - -void -Compilation::visit (AST::IfExprConseqIf &expr) -{ - Bexpression *cond = NULL; - VISIT_POP (expr.get_condition_expr ()->get_locus_slow (), - expr.get_condition_expr ().get (), cond, exprs); - if (cond == NULL) - { - rust_error_at (expr.get_condition_expr ()->get_locus_slow (), - "failed to compile"); - return; - } - - expr.vis_if_block (*this); - Bblock *then_block = scope.PopBlock (); - - // setup else block - Bblock *enclosingScope = NULL; - Location start_location; /* = stmt.locus; FIXME */ - Location end_location; // FIXME - - std::vector<Bvariable *> vars; - auto else_block - = backend->block (scope.GetCurrentFndecl (), scope.CurBlock (), vars, - start_location, end_location); - - scope.PushBlock (else_block); - expr.vis_conseq_if_expr (*this); - // get trailing if required - for (auto &s : stmts) - scope.AddStatement (s); - stmts.clear (); - scope.PopBlock (); - - auto stmt - = backend->if_statement (scope.GetCurrentFndecl (), cond, then_block, - else_block, expr.get_locus ()); - stmts.push_back (stmt); -} - -void -Compilation::visit (AST::IfExprConseqIfLet &expr) -{ - printf ("IfExprConseqIfLet %s\n", expr.as_string ().c_str ()); -} -void -Compilation::visit (AST::IfLetExpr &expr) -{ - printf ("IfLetExpr %s\n", expr.as_string ().c_str ()); -} -void -Compilation::visit (AST::IfLetExprConseqElse &expr) -{ - printf ("IfLetExprConseqElse %s\n", expr.as_string ().c_str ()); -} - -void -Compilation::visit (AST::IfLetExprConseqIf &expr) -{ - printf ("IfLetExprConseqIf %s\n", expr.as_string ().c_str ()); -} - -void -Compilation::visit (AST::IfLetExprConseqIfLet &expr) -{ - printf ("IfLetExprConseqIfLet %s\n", expr.as_string ().c_str ()); -} - -// void Compilation::visit(MatchCase& match_case) {} -/*void -Compilation::visit (AST::MatchCaseBlockExpr &match_case) -{}*/ -/*void -Compilation::visit (AST::MatchCaseExpr &match_case) -{}*/ -void -Compilation::visit (AST::MatchExpr &expr) -{} -void -Compilation::visit (AST::AwaitExpr &expr) -{} -void -Compilation::visit (AST::AsyncBlockExpr &expr) -{} - -// rust-item.h -void -Compilation::visit (AST::TypeParam ¶m) -{} -// void Compilation::visit(WhereClauseItem& item) {} -void -Compilation::visit (AST::LifetimeWhereClauseItem &item) -{} -void -Compilation::visit (AST::TypeBoundWhereClauseItem &item) -{} -void -Compilation::visit (AST::Method &method) -{} -void -Compilation::visit (AST::ModuleBodied &module) -{} -void -Compilation::visit (AST::ModuleNoBody &module) -{} -void -Compilation::visit (AST::ExternCrate &crate) -{} -// void Compilation::visit(UseTree& use_tree) {} -void -Compilation::visit (AST::UseTreeGlob &use_tree) -{} -void -Compilation::visit (AST::UseTreeList &use_tree) -{} -void -Compilation::visit (AST::UseTreeRebind &use_tree) -{} -void -Compilation::visit (AST::UseDeclaration &use_decl) -{} - -void -Compilation::visit (AST::Function &function) -{ - Backend::Btyped_identifier receiver; - std::vector<Backend::Btyped_identifier> parameters; - std::vector<Backend::Btyped_identifier> results; - - for (auto ¶m : function.get_function_params ()) - { - // translate the type - translatedType = NULL; - param.get_type ()->accept_vis (*this); - if (translatedType == NULL) - { - rust_error_at (param.get_locus (), "failed to generate type for parameter"); - return; - } - - auto before = patternBuffer.size (); - param.get_pattern ()->accept_vis (*this); - if (patternBuffer.size () <= before) - { - rust_error_at (param.get_locus (), "failed to analyse parameter name"); - return; - } - - auto numParamsPerType = patternBuffer.size () - before; - for (size_t i = 0; i < numParamsPerType; i++) - { - auto paramName = patternBuffer.back (); - patternBuffer.pop_back (); - parameters.push_back ( - Backend::Btyped_identifier (paramName.get_ident (), - translatedType, param.get_locus ())); - } - } - - Btype *returnType = NULL; - if (function.has_return_type ()) - { - translatedType = NULL; - function.get_return_type ()->accept_vis (*this); - if (translatedType == NULL) - { - rust_fatal_error (function.get_locus (), - "failed to generate type for function"); - return; - } - returnType = translatedType; - - // add into the results: - results.push_back ( - Backend::Btyped_identifier ("_", translatedType, Location ())); - } +// Copyright (C) 2020 Free Software Foundation, Inc. - Btype *fntype = backend->function_type (receiver, parameters, results, NULL, - function.get_locus ()); - Bfunction *fndecl - = backend->function (fntype, function.get_function_name (), "" /* asm_name */, - 0 /* flags */, function.get_locus ()); +// This file is part of GCC. - scope.InsertFunction (function.get_function_name (), fndecl, returnType); - scope.Push (); +// 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. - // setup the params - std::vector<Bvariable *> param_vars; - for (auto ¶m : parameters) - { - bool tree_addressable = false; - auto p = backend->parameter_variable (fndecl, param.name, param.btype, - tree_addressable, param.location); +// 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. - scope.InsertVar (param.name, p); - param_vars.push_back (p); - } +// 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/>. - if (!backend->function_set_parameters (fndecl, param_vars)) - { - rust_error_at (function.get_locus (), "failed to setup parameter variables"); - return; - } - - std::vector<Bvariable *> vars; - for (auto &decl : function.locals) - { - if (!compileVarDecl (fndecl, decl, vars)) - { - rust_error_at (decl->get_locus (), "failed to compile var decl"); - return; - } - } - - // is null for top level functions - nested functions will have an enclosing - // scope - Bblock *enclosingScope = NULL; - Location start_location = function.get_locus (); - Location end_location; - if (function.get_definition ()->get_statements ().size () > 0) - { - end_location - = function.get_definition ()->get_statements ().back ()->get_locus_slow (); - } - - auto code_block = backend->block (fndecl, enclosingScope, vars, - start_location, end_location); - - scope.PushBlock (code_block); - - Bvariable *retDecl = NULL; - if (function.has_return_type ()) - { - bool address_is_taken = false; - Bstatement *ret_var_stmt = NULL; - retDecl = backend->temporary_variable (fndecl, code_block, returnType, - NULL, address_is_taken, - function.get_locus (), &ret_var_stmt); - scope.AddStatement (ret_var_stmt); - } - scope.PushCurrentFunction (function.get_function_name (), fndecl, returnType, - retDecl); - - for (auto &stmt : function.get_definition ()->get_statements ()) - stmt->accept_vis (*this); - - scope.PopBlock (); - - auto body = backend->block_statement (code_block); - if (!backend->function_set_body (fndecl, body)) - { - rust_error_at (function.get_locus (), "failed to set body to function"); - return; - } - - scope.Pop (); - scope.PopCurrentFunction (); - - func_decls.push_back (fndecl); -} - -void -Compilation::visit (AST::TypeAlias &type_alias) -{} - -void -Compilation::visit (AST::StructStruct &struct_item) -{ - std::vector<Backend::Btyped_identifier> fields; - for (auto &field : struct_item.get_fields ()) - { - translatedType = NULL; - field.get_field_type ()->accept_vis (*this); - if (translatedType == NULL) - { - rust_fatal_error ( - struct_item.get_locus () /* StructField is mi sing locus */, - "failed to compile struct field"); - return; - } - - fields.push_back (Backend::Btyped_identifier ( - field.get_field_name (), translatedType, - struct_item.get_locus () /* StructField is mi sing locus */)); - } - - auto compiledStruct - = backend->placeholder_struct_type (struct_item.get_struct_name (), - struct_item.get_locus ()); - bool ok = backend->set_placeholder_struct_type (compiledStruct, fields); - if (!ok) - { - rust_fatal_error (struct_item.get_locus (), "failed to compile struct"); - return; - } - - type_decls.push_back (compiledStruct); - scope.InsertType (struct_item.get_struct_name (), compiledStruct); - scope.InsertStructDecl (struct_item.get_struct_name (), &struct_item); -} - -void -Compilation::visit (AST::TupleStruct &tuple_struct) -{} -void -Compilation::visit (AST::EnumItem &item) -{} -void -Compilation::visit (AST::EnumItemTuple &item) -{} -void -Compilation::visit (AST::EnumItemStruct &item) -{} -void -Compilation::visit (AST::EnumItemDiscriminant &item) -{} -void -Compilation::visit (AST::Enum &enum_item) -{} -void -Compilation::visit (AST::Union &union_item) -{} -void -Compilation::visit (AST::ConstantItem &const_item) -{} -void -Compilation::visit (AST::StaticItem &static_item) -{} -void -Compilation::visit (AST::TraitItemFunc &item) -{} -void -Compilation::visit (AST::TraitItemMethod &item) -{} -void -Compilation::visit (AST::TraitItemConst &item) -{} -void -Compilation::visit (AST::TraitItemType &item) -{} -void -Compilation::visit (AST::Trait &trait) -{} -void -Compilation::visit (AST::InherentImpl &impl) -{} -void -Compilation::visit (AST::TraitImpl &impl) -{} -// void Compilation::visit(ExternalItem& item) {} -void -Compilation::visit (AST::ExternalStaticItem &item) -{} -void -Compilation::visit (AST::ExternalFunctionItem &item) -{} -void -Compilation::visit (AST::ExternBlock &block) -{} - -// rust-macro.h -void -Compilation::visit (AST::MacroMatchFragment &match) -{} -void -Compilation::visit (AST::MacroMatchRepetition &match) -{} -void -Compilation::visit (AST::MacroMatcher &matcher) -{} -void -Compilation::visit (AST::MacroRulesDefinition &rules_def) -{} -void -Compilation::visit (AST::MacroInvocation ¯o_invoc) -{} -void -Compilation::visit (AST::MetaItemPath &meta_item) -{} -void -Compilation::visit (AST::MetaItemSeq &meta_item) -{} -void -Compilation::visit (AST::MetaWord &meta_item) -{} -void -Compilation::visit (AST::MetaNameValueStr &meta_item) -{} -void -Compilation::visit (AST::MetaListPaths &meta_item) -{} -void -Compilation::visit (AST::MetaListNameValueStr &meta_item) -{} - -// rust-pattern.h -void -Compilation::visit (AST::LiteralPattern &pattern) -{ - printf ("LiteralPattern: %s\n", pattern.as_string ().c_str ()); -} - -void -Compilation::visit (AST::IdentifierPattern &pattern) -{ - patternBuffer.push_back (pattern); -} +#include "rust-compile.h" +#include "rust-compile-item.h" -void -Compilation::visit (AST::WildcardPattern &pattern) -{} -// void Compilation::visit(RangePatternBound& bound) {} -void -Compilation::visit (AST::RangePatternBoundLiteral &bound) -{} -void -Compilation::visit (AST::RangePatternBoundPath &bound) -{} -void -Compilation::visit (AST::RangePatternBoundQualPath &bound) -{} -void -Compilation::visit (AST::RangePattern &pattern) -{} -void -Compilation::visit (AST::ReferencePattern &pattern) -{} -// void Compilation::visit(StructPatternField& field) {} -void -Compilation::visit (AST::StructPatternFieldTuplePat &field) -{} -void -Compilation::visit (AST::StructPatternFieldIdentPat &field) -{} -void -Compilation::visit (AST::StructPatternFieldIdent &field) -{} -void -Compilation::visit (AST::StructPattern &pattern) -{} -// void Compilation::visit(TupleStructItems& tuple_items) {} -void -Compilation::visit (AST::TupleStructItemsNoRange &tuple_items) -{} -void -Compilation::visit (AST::TupleStructItemsRange &tuple_items) -{} -void -Compilation::visit (AST::TupleStructPattern &pattern) -{} -// void Compilation::visit(TuplePatternItems& tuple_items) {} -void -Compilation::visit (AST::TuplePatternItemsMultiple &tuple_items) -{} -void -Compilation::visit (AST::TuplePatternItemsRanged &tuple_items) -{} -void -Compilation::visit (AST::TuplePattern &pattern) -{} -void -Compilation::visit (AST::GroupedPattern &pattern) -{} -void -Compilation::visit (AST::SlicePattern &pattern) -{} +namespace Rust { +namespace Compile { -// rust-stmt.h -void -Compilation::visit (AST::EmptyStmt &stmt) +CompileCrate::CompileCrate (HIR::Crate &crate, Context *ctx) + : crate (crate), ctx (ctx) {} -void - -Compilation::visit (AST::LetStmt &stmt) -{ - if (!stmt.has_init_expr ()) - return; - - stmt.get_pattern ()->accept_vis (*this); - for (auto &pattern : patternBuffer) - { - Bvariable *var = NULL; - if (!scope.LookupVar (pattern.get_ident (), &var)) - { - rust_error_at (stmt.get_locus (), "failed to find var decl for %s", - pattern.get_ident ().c_str ()); - return; - } - - varBuffer.push_back (var); - - Bexpression *init = NULL; - VISIT_POP (stmt.get_init_expr ()->get_locus_slow (), stmt.get_init_expr (), init, - exprs); - if (init == NULL) - { - rust_error_at (stmt.get_init_expr ()->get_locus_slow (), - "failed to compile init statement"); - return; - } - auto s = backend->init_statement (scope.GetCurrentFndecl (), var, init); - scope.AddStatement (s); - - varBuffer.pop_back (); - } - patternBuffer.clear (); -} +CompileCrate::~CompileCrate () {} void -Compilation::visit (AST::ExprStmtWithoutBlock &stmt) -{ - stmt.get_expr ()->accept_vis (*this); -} +CompileCrate::Compile (HIR::Crate &crate, Context *ctx) -void -Compilation::visit (AST::ExprStmtWithBlock &stmt) { - Bblock *enclosingScope = NULL; - Location start_location; /* = stmt.locus; FIXME */ - Location end_location; // FIXME - - std::vector<Bvariable *> vars; - auto code_block - = backend->block (scope.GetCurrentFndecl (), scope.CurBlock (), vars, - start_location, end_location); - - scope.PushBlock (code_block); - stmt.get_expr ()->accept_vis (*this); - - // get trailing if required - for (auto &s : stmts) - { - scope.AddStatement (s); - } - stmts.clear (); - - scope.PopBlock (); - - auto body = backend->block_statement (code_block); - scope.AddStatement (body); + CompileCrate c (crate, ctx); + c.go (); } -// rust-type.h -void -Compilation::visit (AST::TraitBound &bound) -{} -void -Compilation::visit (AST::ImplTraitType &type) -{} -void -Compilation::visit (AST::TraitObjectType &type) -{} -void -Compilation::visit (AST::ParenthesisedType &type) -{} -void -Compilation::visit (AST::ImplTraitTypeOneBound &type) -{} -void -Compilation::visit (AST::TraitObjectTypeOneBound &type) -{} -void -Compilation::visit (AST::TupleType &type) -{} -void -Compilation::visit (AST::NeverType &type) -{} -void -Compilation::visit (AST::RawPointerType &type) -{} -void -Compilation::visit (AST::ReferenceType &type) -{} - void -Compilation::visit (AST::ArrayType &type) +CompileCrate::go () { - Btype *elementType; - translatedType = nullptr; - type.get_elem_type ()->accept_vis (*this); - if (translatedType == nullptr) - { - rust_error_at (type.get_locus (), - "Failed to compile element type for array"); - return; - } - elementType = translatedType; - - Bexpression *length = nullptr; - VISIT_POP (type.get_size_expr ()->get_locus_slow (), type.get_size_expr (), - length, exprs); - if (length == nullptr) - { - rust_error_at (type.get_size_expr ()->get_locus_slow (), - "failed to size for array type"); - return; - } - - translatedType = backend->array_type (elementType, length); + for (auto it = crate.items.begin (); it != crate.items.end (); it++) + CompileItem::compile (it->get (), ctx); } -void -Compilation::visit (AST::SliceType &type) -{} -void -Compilation::visit (AST::InferredType &type) -{} -void -Compilation::visit (AST::BareFunctionType &type) -{} - } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile.h b/gcc/rust/backend/rust-compile.h index 88c8318..18f3e54 100644 --- a/gcc/rust/backend/rust-compile.h +++ b/gcc/rust/backend/rust-compile.h @@ -1,257 +1,47 @@ -#pragma once +// Copyright (C) 2020 Free Software Foundation, Inc. -#include "rust-system.h" -#include "rust-ast-full.h" -#include "rust-ast-visitor.h" -#include "rust-backend.h" -#include "cscope.h" +// This file is part of GCC. -namespace Rust { -namespace Compile { +// 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. -class Compilation : public AST::ASTVisitor -{ -public: - static bool Compile (AST::Crate &crate, ::Backend *backend); +// 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. - ~Compilation (); +// 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/>. - // visitor impl - // rust-ast.h - // virtual void visit(AttrInput& attr_input); - // virtual void visit(TokenTree& token_tree); - // virtual void visit(MacroMatch& macro_match); - virtual void visit (AST::Token &tok); - virtual void visit (AST::DelimTokenTree &delim_tok_tree); - virtual void visit (AST::AttrInputMetaItemContainer &input); - // virtual void visit(MetaItem& meta_item); - // virtual void vsit(Stmt& stmt); - // virtual void visit(Expr& expr); - virtual void visit (AST::IdentifierExpr &ident_expr); - // virtual void visit(Pattern& pattern); - // virtual void visit(Type& type); - // virtual void visit(TypeParamBound& type_param_bound); - virtual void visit (AST::Lifetime &lifetime); - // virtual void visit(GenericParam& generic_param); - virtual void visit (AST::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 (AST::MacroInvocationSemi ¯o); +#ifndef RUST_COMPILE_H +#define RUST_COMPILE_H - // rust-path.h - virtual void visit (AST::PathInExpression &path); - virtual void visit (AST::TypePathSegment &segment); - virtual void visit (AST::TypePathSegmentGeneric &segment); - virtual void visit (AST::TypePathSegmentFunction &segment); - virtual void visit (AST::TypePath &path); - virtual void visit (AST::QualifiedPathInExpression &path); - virtual void visit (AST::QualifiedPathInType &path); - - // rust-expr.h - virtual void visit (AST::LiteralExpr &expr); - virtual void visit (AST::AttrInputLiteral &attr_input); - virtual void visit (AST::MetaItemLitExpr &meta_item); - virtual void visit (AST::MetaItemPathLit &meta_item); - virtual void visit (AST::BorrowExpr &expr); - virtual void visit (AST::DereferenceExpr &expr); - virtual void visit (AST::ErrorPropagationExpr &expr); - virtual void visit (AST::NegationExpr &expr); - virtual void visit (AST::ArithmeticOrLogicalExpr &expr); - virtual void visit (AST::ComparisonExpr &expr); - virtual void visit (AST::LazyBooleanExpr &expr); - virtual void visit (AST::TypeCastExpr &expr); - virtual void visit (AST::AssignmentExpr &expr); - virtual void visit (AST::CompoundAssignmentExpr &expr); - virtual void visit (AST::GroupedExpr &expr); - // virtual void visit(ArrayElems& elems); - virtual void visit (AST::ArrayElemsValues &elems); - virtual void visit (AST::ArrayElemsCopied &elems); - virtual void visit (AST::ArrayExpr &expr); - virtual void visit (AST::ArrayIndexExpr &expr); - virtual void visit (AST::TupleExpr &expr); - virtual void visit (AST::TupleIndexExpr &expr); - virtual void visit (AST::StructExprStruct &expr); - // virtual void visit(StructExprField& field); - virtual void visit (AST::StructExprFieldIdentifier &field); - virtual void visit (AST::StructExprFieldIdentifierValue &field); - virtual void visit (AST::StructExprFieldIndexValue &field); - virtual void visit (AST::StructExprStructFields &expr); - virtual void visit (AST::StructExprStructBase &expr); - virtual void visit (AST::StructExprTuple &expr); - virtual void visit (AST::StructExprUnit &expr); - // virtual void visit(EnumExprField& field); - virtual void visit (AST::EnumExprFieldIdentifier &field); - virtual void visit (AST::EnumExprFieldIdentifierValue &field); - virtual void visit (AST::EnumExprFieldIndexValue &field); - virtual void visit (AST::EnumExprStruct &expr); - virtual void visit (AST::EnumExprTuple &expr); - virtual void visit (AST::EnumExprFieldless &expr); - virtual void visit (AST::CallExpr &expr); - virtual void visit (AST::MethodCallExpr &expr); - virtual void visit (AST::FieldAccessExpr &expr); - virtual void visit (AST::ClosureExprInner &expr); - virtual void visit (AST::BlockExpr &expr); - virtual void visit (AST::ClosureExprInnerTyped &expr); - virtual void visit (AST::ContinueExpr &expr); - virtual void visit (AST::BreakExpr &expr); - virtual void visit (AST::RangeFromToExpr &expr); - virtual void visit (AST::RangeFromExpr &expr); - virtual void visit (AST::RangeToExpr &expr); - virtual void visit (AST::RangeFullExpr &expr); - virtual void visit (AST::RangeFromToInclExpr &expr); - virtual void visit (AST::RangeToInclExpr &expr); - virtual void visit (AST::ReturnExpr &expr); - virtual void visit (AST::UnsafeBlockExpr &expr); - virtual void visit (AST::LoopExpr &expr); - virtual void visit (AST::WhileLoopExpr &expr); - virtual void visit (AST::WhileLetLoopExpr &expr); - virtual void visit (AST::ForLoopExpr &expr); - virtual void visit (AST::IfExpr &expr); - virtual void visit (AST::IfExprConseqElse &expr); - virtual void visit (AST::IfExprConseqIf &expr); - virtual void visit (AST::IfExprConseqIfLet &expr); - virtual void visit (AST::IfLetExpr &expr); - virtual void visit (AST::IfLetExprConseqElse &expr); - virtual void visit (AST::IfLetExprConseqIf &expr); - virtual void visit (AST::IfLetExprConseqIfLet &expr); - // virtual void visit(MatchCase& match_case); - // virtual void visit (AST::MatchCaseBlockExpr &match_case); - // virtual void visit (AST::MatchCaseExpr &match_case); - virtual void visit (AST::MatchExpr &expr); - virtual void visit (AST::AwaitExpr &expr); - virtual void visit (AST::AsyncBlockExpr &expr); - - // rust-item.h - virtual void visit (AST::TypeParam ¶m); - // virtual void visit(WhereClauseItem& item); - virtual void visit (AST::LifetimeWhereClauseItem &item); - virtual void visit (AST::TypeBoundWhereClauseItem &item); - virtual void visit (AST::Method &method); - virtual void visit (AST::ModuleBodied &module); - virtual void visit (AST::ModuleNoBody &module); - virtual void visit (AST::ExternCrate &crate); - // virtual void visit(UseTree& use_tree); - virtual void visit (AST::UseTreeGlob &use_tree); - virtual void visit (AST::UseTreeList &use_tree); - virtual void visit (AST::UseTreeRebind &use_tree); - virtual void visit (AST::UseDeclaration &use_decl); - virtual void visit (AST::Function &function); - virtual void visit (AST::TypeAlias &type_alias); - virtual void visit (AST::StructStruct &struct_item); - virtual void visit (AST::TupleStruct &tuple_struct); - virtual void visit (AST::EnumItem &item); - virtual void visit (AST::EnumItemTuple &item); - virtual void visit (AST::EnumItemStruct &item); - virtual void visit (AST::EnumItemDiscriminant &item); - virtual void visit (AST::Enum &enum_item); - virtual void visit (AST::Union &union_item); - virtual void visit (AST::ConstantItem &const_item); - virtual void visit (AST::StaticItem &static_item); - virtual void visit (AST::TraitItemFunc &item); - virtual void visit (AST::TraitItemMethod &item); - virtual void visit (AST::TraitItemConst &item); - virtual void visit (AST::TraitItemType &item); - virtual void visit (AST::Trait &trait); - virtual void visit (AST::InherentImpl &impl); - virtual void visit (AST::TraitImpl &impl); - // virtual void visit(ExternalItem& item); - virtual void visit (AST::ExternalStaticItem &item); - virtual void visit (AST::ExternalFunctionItem &item); - virtual void visit (AST::ExternBlock &block); - - // rust-macro.h - virtual void visit (AST::MacroMatchFragment &match); - virtual void visit (AST::MacroMatchRepetition &match); - virtual void visit (AST::MacroMatcher &matcher); - virtual void visit (AST::MacroRulesDefinition &rules_def); - virtual void visit (AST::MacroInvocation ¯o_invoc); - virtual void visit (AST::MetaItemPath &meta_item); - virtual void visit (AST::MetaItemSeq &meta_item); - virtual void visit (AST::MetaWord &meta_item); - virtual void visit (AST::MetaNameValueStr &meta_item); - virtual void visit (AST::MetaListPaths &meta_item); - virtual void visit (AST::MetaListNameValueStr &meta_item); +#include "rust-system.h" +#include "rust-hir-full.h" +#include "rust-compile-context.h" - // rust-pattern.h - virtual void visit (AST::LiteralPattern &pattern); - virtual void visit (AST::IdentifierPattern &pattern); - virtual void visit (AST::WildcardPattern &pattern); - // virtual void visit(RangePatternBound& bound); - virtual void visit (AST::RangePatternBoundLiteral &bound); - virtual void visit (AST::RangePatternBoundPath &bound); - virtual void visit (AST::RangePatternBoundQualPath &bound); - virtual void visit (AST::RangePattern &pattern); - virtual void visit (AST::ReferencePattern &pattern); - // virtual void visit(StructPatternField& field); - virtual void visit (AST::StructPatternFieldTuplePat &field); - virtual void visit (AST::StructPatternFieldIdentPat &field); - virtual void visit (AST::StructPatternFieldIdent &field); - virtual void visit (AST::StructPattern &pattern); - // virtual void visit(TupleStructItems& tuple_items); - virtual void visit (AST::TupleStructItemsNoRange &tuple_items); - virtual void visit (AST::TupleStructItemsRange &tuple_items); - virtual void visit (AST::TupleStructPattern &pattern); - // virtual void visit(TuplePatternItems& tuple_items); - virtual void visit (AST::TuplePatternItemsMultiple &tuple_items); - virtual void visit (AST::TuplePatternItemsRanged &tuple_items); - virtual void visit (AST::TuplePattern &pattern); - virtual void visit (AST::GroupedPattern &pattern); - virtual void visit (AST::SlicePattern &pattern); +namespace Rust { +namespace Compile { - // rust-stmt.h - virtual void visit (AST::EmptyStmt &stmt); - virtual void visit (AST::LetStmt &stmt); - virtual void visit (AST::ExprStmtWithoutBlock &stmt); - virtual void visit (AST::ExprStmtWithBlock &stmt); +class CompileCrate +{ +public: + static void Compile (HIR::Crate &crate, Context *ctx); - // rust-type.h - virtual void visit (AST::TraitBound &bound); - virtual void visit (AST::ImplTraitType &type); - virtual void visit (AST::TraitObjectType &type); - virtual void visit (AST::ParenthesisedType &type); - virtual void visit (AST::ImplTraitTypeOneBound &type); - virtual void visit (AST::TraitObjectTypeOneBound &type); - virtual void visit (AST::TupleType &type); - virtual void visit (AST::NeverType &type); - virtual void visit (AST::RawPointerType &type); - virtual void visit (AST::ReferenceType &type); - virtual void visit (AST::ArrayType &type); - virtual void visit (AST::SliceType &type); - virtual void visit (AST::InferredType &type); - virtual void visit (AST::BareFunctionType &type); + ~CompileCrate (); private: - Compilation (AST::Crate &crate, Backend *backend); - bool go (); - - AST::Crate &crate; - Backend *backend; + CompileCrate (HIR::Crate &crate, Context *ctx); + void go (); - // utils - bool compileVarDecl (Bfunction *fndecl, AST::LetStmt *stmt, - std::vector<Bvariable *> &vars); - - Bexpression *compileBooleanLiteral (std::string val); - Bexpression *compileFloatLiteral (std::string val, Location locus); - Bexpression *compileIntegerLiteral (std::string val, Location locus); - - // state - Scope scope; - ::Btype *translatedType; - std::vector<AST::IdentifierPattern> patternBuffer; - std::vector< ::Bexpression *> exprs; - std::vector< ::Bstatement *> stmts; - std::vector< ::Bvariable *> varBuffer; - std::vector<AST::StructStruct *> structBuffer; - std::vector<std::vector< ::Bexpression *> > arrayConsStack; - - // careful these are the vectors we pass into the GCC middle-end - std::vector< ::Btype *> type_decls; - std::vector< ::Bvariable *> var_decls; - std::vector< ::Bexpression *> const_decls; - std::vector< ::Bfunction *> func_decls; + HIR::Crate &crate; + Context *ctx; }; } // namespace Compile } // namespace Rust + +#endif // RUST_COMPILE_H |