diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/crate.hpp | 1 | ||||
-rw-r--r-- | src/hir/deserialise.cpp | 3 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 26 | ||||
-rw-r--r-- | src/hir/hir.cpp | 20 | ||||
-rw-r--r-- | src/hir/hir.hpp | 11 | ||||
-rw-r--r-- | src/hir/item_path.hpp | 6 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 8 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 2 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 10 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 4 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 10 | ||||
-rw-r--r-- | src/hir_expand/const_eval_full.cpp | 4 | ||||
-rw-r--r-- | src/hir_expand/erased_types.cpp | 12 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/mir/visit_crate_mir.cpp | 2 | ||||
-rw-r--r-- | src/trans/codegen.cpp | 8 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 59 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 221 | ||||
-rw-r--r-- | src/trans/main_bindings.hpp | 3 |
19 files changed, 259 insertions, 155 deletions
diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index c51dacf5..b74012a3 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -54,6 +54,7 @@ class ExternCrate { public: ::std::string m_name; + ::std::string m_filename; ::HIR::CratePtr m_hir; ExternCrate(const ::std::string& name, const ::std::string& path); diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index d7dd74fe..40fd1aca 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -494,6 +494,7 @@ namespace { TRACE_FUNCTION; ::HIR::Function rv { + false, deserialise_linkage(), static_cast< ::HIR::Function::Receiver>( m_in.read_tag() ), m_in.read_string(), @@ -1072,7 +1073,7 @@ namespace { for(size_t i = 0; i < n; i ++) { auto ext_crate_name = m_in.read_string(); - rv.m_ext_crates.insert( ::std::make_pair(ext_crate_name, ::HIR::CratePtr{}) ); + rv.m_ext_crates.insert( ::std::make_pair(ext_crate_name, ::HIR::ExternCrate{}) ); } } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index b80759ff..927239ff 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -23,6 +23,7 @@ ::HIR::SimplePath path_Sized; ::std::string g_core_crate; +::std::string g_crate_name; ::HIR::Crate* g_crate_ptr = nullptr; // -------------------------------------------------------------------- @@ -498,6 +499,8 @@ { TU_IFLET(::AST::Path::Class, path.m_class, Absolute, e, ::HIR::SimplePath rv( e.crate ); + if( rv.m_crate_name == "" ) + rv.m_crate_name = g_crate_name; for( const auto& node : e.nodes ) { if( ! node.args().is_empty() ) @@ -914,6 +917,8 @@ namespace { ::HIR::Trait LowerHIR_Trait(::HIR::SimplePath trait_path, const ::AST::Trait& f) { TRACE_FUNCTION_F(trait_path); + trait_path.m_crate_name = g_crate_name; + bool trait_reqires_sized = false; auto params = LowerHIR_GenericParams(f.params(), &trait_reqires_sized); @@ -985,7 +990,9 @@ namespace { ), (Function, ::HIR::TypeRef self_type {"Self", 0xFFFF}; - rv.m_values.insert( ::std::make_pair(item.name, ::HIR::TraitValueItem::make_Function( LowerHIR_Function(item_path, item.data.attrs, i, self_type) )) ); + auto fcn = LowerHIR_Function(item_path, item.data.attrs, i, self_type); + fcn.m_save_code = true; + rv.m_values.insert( ::std::make_pair(item.name, ::HIR::TraitValueItem::make_Function( mv$(fcn) )) ); ), (Static, if( i.s_class() == ::AST::Static::CONST ) @@ -1061,6 +1068,13 @@ namespace { } } + bool force_emit = false; + if( const auto* a = attrs.get("inline") ) + { + (void)a; + force_emit = true; + } + ::HIR::Linkage linkage; // Convert #[link_name/no_mangle] attributes into the name @@ -1094,6 +1108,7 @@ namespace { } return ::HIR::Function { + force_emit, mv$(linkage), receiver, f.abi(), f.is_unsafe(), f.is_const(), @@ -1478,8 +1493,11 @@ public: ::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate) { ::HIR::Crate rv; + rv.m_crate_name = crate.m_crate_name; + g_crate_ptr = &rv; - g_core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? "" : "core"); + g_crate_name = crate.m_crate_name; + g_core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? crate.m_crate_name : "core"); auto& macros = rv.m_exported_macros; // - Extract exported macros @@ -1544,11 +1562,11 @@ public: ERROR(sp, E0000, "Conflicting definitions of lang item '" << name << "'. " << path << " and " << irv.first->second); } } - rv.m_ext_crates.insert( ::std::make_pair( ext_crate.first, mv$(ext_crate.second.m_hir) ) ); + rv.m_ext_crates.insert( ::std::make_pair( ext_crate.first, ::HIR::ExternCrate { mv$(ext_crate.second.m_hir), ext_crate.second.m_filename } ) ); } path_Sized = rv.get_lang_item_path(sp, "sized"); - rv.m_root_module = LowerHIR_Module( crate.m_root_module, ::HIR::ItemPath() ); + rv.m_root_module = LowerHIR_Module( crate.m_root_module, ::HIR::ItemPath(crate.m_crate_name) ); LowerHIR_Module_Impls(crate.m_root_module, rv); diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index f5d75101..d4a4c9be 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -733,9 +733,9 @@ const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ASSERT_BUG(sp, path.m_components.size() > (ignore_last_node ? 1 : 0), "get_typeitem_by_path received invlaid path - " << path); const ::HIR::Module* mod; - if( !ignore_crate_name && path.m_crate_name != "" ) { - ASSERT_BUG(sp, m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &m_ext_crates.at(path.m_crate_name)->m_root_module; + if( !ignore_crate_name && path.m_crate_name != m_crate_name ) { + ASSERT_BUG(sp, m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded for " << path); + mod = &m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { mod = &this->m_root_module; @@ -766,10 +766,10 @@ const ::HIR::Module& ::HIR::Crate::get_mod_by_path(const Span& sp, const ::HIR:: { if( path.m_components.size() == 0 ) { - if( path.m_crate_name != "" ) + if( path.m_crate_name != m_crate_name ) { ASSERT_BUG(sp, m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - return m_ext_crates.at(path.m_crate_name)->m_root_module; + return m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { @@ -834,9 +834,9 @@ const ::HIR::ValueItem& ::HIR::Crate::get_valitem_by_path(const Span& sp, const BUG(sp, "get_valitem_by_path received invalid path"); } const ::HIR::Module* mod; - if( !ignore_crate_name && path.m_crate_name != "" ) { + if( !ignore_crate_name && path.m_crate_name != m_crate_name ) { ASSERT_BUG(sp, m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &m_ext_crates.at(path.m_crate_name)->m_root_module; + mod = &m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { mod = &this->m_root_module; @@ -887,7 +887,7 @@ bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR: } for( const auto& ec : this->m_ext_crates ) { - if( ec.second->find_trait_impls(trait, type, ty_res, callback) ) { + if( ec.second.m_data->find_trait_impls(trait, type, ty_res, callback) ) { return true; } } @@ -907,7 +907,7 @@ bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const : } for( const auto& ec : this->m_ext_crates ) { - if( ec.second->find_auto_trait_impls(trait, type, ty_res, callback) ) { + if( ec.second.m_data->find_auto_trait_impls(trait, type, ty_res, callback) ) { return true; } } @@ -927,7 +927,7 @@ bool ::HIR::Crate::find_type_impls(const ::HIR::TypeRef& type, t_cb_resolve_type for( const auto& ec : this->m_ext_crates ) { //DEBUG("- " << ec.first); - if( ec.second->find_type_impls(type, ty_res, callback) ) { + if( ec.second.m_data->find_type_impls(type, ty_res, callback) ) { return true; } } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 66f4babc..9b40ad1a 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -122,6 +122,7 @@ public: typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > args_t; + bool m_save_code; // Filled by enumerate, defaults to false Linkage m_linkage; Receiver m_receiver; @@ -402,9 +403,17 @@ public: } }; +class ExternCrate +{ +public: + ::HIR::CratePtr m_data; + ::std::string m_filename; +}; class Crate { public: + ::std::string m_crate_name; + Module m_root_module; /// Impl blocks on just a type @@ -419,7 +428,7 @@ public: /// Language items avaliable through this crate (includes ones from loaded externs) ::std::unordered_map< ::std::string, ::HIR::SimplePath> m_lang_items; - ::std::unordered_map< ::std::string, ::HIR::CratePtr> m_ext_crates; + ::std::unordered_map< ::std::string, ExternCrate> m_ext_crates; /// Method called to populate runtime state after deserialisation /// See hir/crate_post_load.cpp diff --git a/src/hir/item_path.hpp b/src/hir/item_path.hpp index 606c6817..f0c591af 100644 --- a/src/hir/item_path.hpp +++ b/src/hir/item_path.hpp @@ -17,8 +17,9 @@ public: const ::HIR::SimplePath* trait = nullptr; const ::HIR::PathParams* trait_params = nullptr; const char* name = nullptr; + const char* crate_name = nullptr; - ItemPath() {} + ItemPath(const ::std::string& crate): crate_name(crate.c_str()) {} ItemPath(const ItemPath& p, const char* n): parent(&p), name(n) @@ -45,7 +46,8 @@ public: } else { assert(!name); - return ::HIR::SimplePath(); + assert(crate_name); + return ::HIR::SimplePath(crate_name); } } ::HIR::Path get_full_path() const { diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 4feece50..0f444583 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -441,10 +441,10 @@ namespace { ) } - void serialise(const ::HIR::ExprPtr& exp) + void serialise(const ::HIR::ExprPtr& exp, bool save_mir=true) { - m_out.write_bool( (bool)exp.m_mir ); - if( exp.m_mir ) { + m_out.write_bool( (bool)exp.m_mir && save_mir ); + if( exp.m_mir && save_mir ) { serialise(*exp.m_mir); } serialise_vec( exp.m_erased_types ); @@ -763,7 +763,7 @@ namespace { serialise(fcn.m_return); DEBUG("m_args = " << fcn.m_args); - serialise(fcn.m_code); + serialise(fcn.m_code, fcn.m_save_code); } void serialise(const ::HIR::Constant& item) { diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 40bc14a4..02cc5948 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -14,7 +14,7 @@ void ::HIR::Visitor::visit_crate(::HIR::Crate& crate) { - this->visit_module(::HIR::ItemPath(), crate.m_root_module ); + this->visit_module(::HIR::ItemPath(crate.m_crate_name), crate.m_root_module ); for( auto& ty_impl : crate.m_type_impls ) { diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 7cb4e402..72912972 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -29,9 +29,9 @@ namespace { { // NOTE: Can't share with HIR::Crate::get_typeitem_by_path because it has to handle enum variants const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { + if( path.m_crate_name != crate.m_crate_name ) { ASSERT_BUG(sp, crate.m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &crate.m_ext_crates.at(path.m_crate_name)->m_root_module; + mod = &crate.m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { mod = &crate.m_root_module; @@ -182,9 +182,9 @@ namespace { const ::HIR::Enum* enm = nullptr; const auto& path = pe.m_path; const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { + if( path.m_crate_name != m_crate.m_crate_name ) { ASSERT_BUG(sp, m_crate.m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &m_crate.m_ext_crates.at(path.m_crate_name)->m_root_module; + mod = &m_crate.m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { mod = &m_crate.m_root_module; @@ -682,6 +682,6 @@ void ConvertHIR_Bind(::HIR::Crate& crate) // Also visit extern crates to update their pointers for(auto& ec : crate.m_ext_crates) { - exp.visit_crate( *ec.second ); + exp.visit_crate( *ec.second.m_data ); } } diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 7318f2cf..8ee78af9 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -99,9 +99,9 @@ namespace { EntPtr get_ent_simplepath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path, EntNS ns) { const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { + if( path.m_crate_name != crate.m_crate_name ) { ASSERT_BUG(sp, crate.m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &crate.m_ext_crates.at(path.m_crate_name)->m_root_module; + mod = &crate.m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { mod = &crate.m_root_module; diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 51b99d5a..180ed89a 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -294,7 +294,7 @@ namespace { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( ::std::string("call_once"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { - ::HIR::Linkage {}, + false, ::HIR::Linkage {}, ::HIR::Function::Receiver::Value, ABI_RUST, false, false, {}, @@ -332,7 +332,7 @@ namespace { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( ::std::string("call_mut"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { - ::HIR::Linkage {}, + false, ::HIR::Linkage {}, ::HIR::Function::Receiver::BorrowUnique, ABI_RUST, false, false, {}, @@ -368,7 +368,7 @@ namespace { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( ::std::string("call"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { - ::HIR::Linkage {}, + false, ::HIR::Linkage {}, ::HIR::Function::Receiver::BorrowShared, ABI_RUST, false, false, {}, @@ -1007,14 +1007,14 @@ namespace { Span sp; unsigned int closure_count = 0; - ::HIR::SimplePath root_mod_path("",{}); + ::HIR::SimplePath root_mod_path(crate.m_crate_name,{}); m_cur_mod_path = &root_mod_path; m_new_type = [&](auto s)->auto { auto name = FMT("closure_I_" << closure_count); closure_count += 1; auto boxed = box$(( ::HIR::VisEnt< ::HIR::TypeItem> { false, ::HIR::TypeItem( mv$(s) ) } )); crate.m_root_module.m_mod_items.insert( ::std::make_pair(name, mv$(boxed)) ); - return ::HIR::SimplePath() + name; + return ::HIR::SimplePath(crate.m_crate_name, {}) + name; }; ::HIR::Visitor::visit_crate(crate); diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp index d2fa3a76..102bb84c 100644 --- a/src/hir_expand/const_eval_full.cpp +++ b/src/hir_expand/const_eval_full.cpp @@ -128,9 +128,9 @@ namespace { EntPtr get_ent_simplepath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path, EntNS ns) { const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { + if( path.m_crate_name != crate.m_crate_name ) { ASSERT_BUG(sp, crate.m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &crate.m_ext_crates.at(path.m_crate_name)->m_root_module; + mod = &crate.m_ext_crates.at(path.m_crate_name).m_data->m_root_module; } else { mod = &crate.m_root_module; diff --git a/src/hir_expand/erased_types.cpp b/src/hir_expand/erased_types.cpp index 44bb17de..336e36b8 100644 --- a/src/hir_expand/erased_types.cpp +++ b/src/hir_expand/erased_types.cpp @@ -125,7 +125,7 @@ namespace { public ::HIR::Visitor { StaticTraitResolve m_resolve; - ::HIR::ItemPath m_fcn_path; + const ::HIR::ItemPath* m_fcn_path; public: OuterVisitor(const ::HIR::Crate& crate): m_resolve(crate) @@ -142,9 +142,9 @@ namespace { void visit_function(::HIR::ItemPath p, ::HIR::Function& fcn) override { - m_fcn_path = p; + m_fcn_path = &p; ::HIR::Visitor::visit_function(p, fcn); - m_fcn_path = ::HIR::ItemPath(); + m_fcn_path = nullptr; } void visit_type(::HIR::TypeRef& ty) override @@ -152,13 +152,13 @@ namespace { static const Span sp; if( ty.m_data.is_ErasedType() ) { - ASSERT_BUG(sp, m_fcn_path.get_name(), ""); + ASSERT_BUG(sp, m_fcn_path, "Erased type outside of a function"); const auto& e = ty.m_data.as_ErasedType(); TU_MATCHA( (e.m_origin.m_data), (pe), (Generic, - if( m_fcn_path == pe.m_path ) { + if( *m_fcn_path == pe.m_path ) { ::HIR::Visitor::visit_type(ty); return ; } @@ -170,7 +170,7 @@ namespace { BUG(sp, "UfcsKnown not supported"); ), (UfcsInherent, - if( m_fcn_path.parent && m_fcn_path.parent->ty && !m_fcn_path.parent->trait && *m_fcn_path.parent->ty == *pe.type && m_fcn_path.name == pe.item ) { + if( m_fcn_path->parent && m_fcn_path->parent->ty && !m_fcn_path->parent->trait && *m_fcn_path->parent->ty == *pe.type && m_fcn_path->name == pe.item ) { ::HIR::Visitor::visit_type(ty); return ; } diff --git a/src/main.cpp b/src/main.cpp index d6d25fb1..31c02092 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -435,10 +435,10 @@ int main(int argc, char *argv[]) // ERROR? break; case ::AST::Crate::Type::RustLib: { + #if 1 // Generate a .o - #if 0 TransList items = CompilePhase<TransList>("Trans Enumerate", [&]() { return Trans_Enumerate_Public(*hir_crate); }); - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".c", *hir_crate, items, false); }); + CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", *hir_crate, items, false); }); #endif // Save a loadable HIR dump diff --git a/src/mir/visit_crate_mir.cpp b/src/mir/visit_crate_mir.cpp index ba4acf8e..93d5f6ea 100644 --- a/src/mir/visit_crate_mir.cpp +++ b/src/mir/visit_crate_mir.cpp @@ -20,7 +20,7 @@ void MIR::OuterVisitor::visit_type(::HIR::TypeRef& ty) this->visit_type( *e.inner ); DEBUG("Array size " << ty); if( e.size ) { - m_cb(m_resolve, ::HIR::ItemPath(), *e.size, {}, ::HIR::TypeRef(::HIR::CoreType::Usize)); + m_cb(m_resolve, ::HIR::ItemPath(""), *e.size, {}, ::HIR::TypeRef(::HIR::CoreType::Usize)); } ) else { diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index e2047e01..29b42325 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -118,11 +118,11 @@ void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, cons for(const auto& a : fcn.m_args) args.push_back(::std::make_pair( ::HIR::Pattern{}, pp.monomorph(resolve, a.second) )); auto mir = Trans_Monomorphise(resolve, pp, fcn.m_code.m_mir); - MIR_Validate(resolve, ::HIR::ItemPath(), *mir, args, ret_type); - MIR_Cleanup(resolve, ::HIR::ItemPath(), *mir, args, ret_type); + MIR_Validate(resolve, ::HIR::ItemPath(""), *mir, args, ret_type); + MIR_Cleanup(resolve, ::HIR::ItemPath(""), *mir, args, ret_type); // TODO: MIR Optimisation - //MIR_Optimise(resolve, ::HIR::ItemPath(), *mir, args, ret_type); - MIR_Validate(resolve, ::HIR::ItemPath(), *mir, args, ret_type); + //MIR_Optimise(resolve, ::HIR::ItemPath(""), *mir, args, ret_type); + MIR_Validate(resolve, ::HIR::ItemPath(""), *mir, args, ret_type); codegen->emit_function_code(path, fcn, ent.second->pp, mir); } else { diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index ce351a57..2d2eca27 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -30,6 +30,10 @@ namespace { const ::HIR::Crate& m_crate; ::StaticTraitResolve m_resolve; + + ::std::string m_outfile_path; + ::std::string m_outfile_path_c; + ::std::ofstream m_of; const ::MIR::TypeResolve* m_mir_res; @@ -38,7 +42,9 @@ namespace { CodeGenerator_C(const ::HIR::Crate& crate, const ::std::string& outfile): m_crate(crate), m_resolve(crate), - m_of(outfile) + m_outfile_path(outfile), + m_outfile_path_c(outfile + ".c"), + m_of(m_outfile_path_c) { m_of << "/*\n" @@ -61,17 +67,22 @@ namespace { << "\n" << "extern void _Unwind_Resume(void) __attribute__((noreturn));\n" << "\n" - << "int slice_cmp(SLICE_PTR l, SLICE_PTR r) {\n" + << "static inline int slice_cmp(SLICE_PTR l, SLICE_PTR r) {\n" << "\tint rv = memcmp(l.PTR, r.PTR, l.META < r.META ? l.META : r.META);\n" << "\tif(rv != 0) return rv;\n" << "\tif(l.META < r.META) return -1;\n" << "\tif(l.META > r.META) return 1;\n" << "\treturn 0;\n" << "}\n" - << "SLICE_PTR make_sliceptr(void* ptr, size_t s) { SLICE_PTR rv = { ptr, s }; return rv; }\n" - << "TRAITOBJ_PTR make_traitobjptr(void* ptr, void* vt) { TRAITOBJ_PTR rv = { ptr, vt }; return rv; }\n" + << "static inline SLICE_PTR make_sliceptr(void* ptr, size_t s) { SLICE_PTR rv = { ptr, s }; return rv; }\n" + << "static inline TRAITOBJ_PTR make_traitobjptr(void* ptr, void* vt) { TRAITOBJ_PTR rv = { ptr, vt }; return rv; }\n" << "\n" - << "size_t max(size_t a, size_t b) { return a < b ? b : a; }\n" + << "static inline size_t max(size_t a, size_t b) { return a < b ? b : a; }\n" + << "static inline unsigned __int128 __builtin_bswap128(unsigned __int128 v) {\n" + << "\tuint64_t lo = __builtin_bswap64((uint64_t)v);\n" + << "\tuint64_t hi = __builtin_bswap64((uint64_t)(v>>64));\n" + << "\treturn ((unsigned __int128)lo << 64) | (unsigned __int128)hi;\n" + << "}\n" << "\n" ; } @@ -91,12 +102,48 @@ namespace { m_of << "int main(int argc, const char* argv[]) {\n" << "\t" << Trans_Mangle( ::HIR::GenericPath(m_resolve.m_crate.get_lang_item_path(Span(), "start")) ) << "(" - << "(uint8_t*)" << Trans_Mangle( ::HIR::GenericPath(::HIR::SimplePath("", {"main"})) ) << ", argc, (uint8_t**)argv" + << "(uint8_t*)" << Trans_Mangle( ::HIR::GenericPath(::HIR::SimplePath(m_crate.m_crate_name, {"main"})) ) << ", argc, (uint8_t**)argv" << ");\n" << "}\n"; } + m_of.flush(); + // Execute $CC with the required libraries + ::std::vector<::std::string> tmp; + ::std::vector<const char*> args; + args.push_back("gcc"); + args.push_back("-pthread"); + args.push_back("-o"); + args.push_back(m_outfile_path.c_str()); + args.push_back(m_outfile_path_c.c_str()); + if( is_executable ) + { + for( const auto& crate : m_crate.m_ext_crates ) + { + // TODO: Get the path from the CratePtr + //tmp.push_back(crate.second.m_filename + ".o"); + tmp.push_back("output/lib" + crate.first + ".hir.o"); + args.push_back(tmp.back().c_str()); + } + args.push_back("-lm"); + args.push_back("-ldl"); + args.push_back("-z"); args.push_back("muldefs"); + } + else + { + args.push_back("-c"); + } + + ::std::stringstream cmd_ss; + for(const auto& arg : args) + { + cmd_ss << "\"" << FmtEscaped(arg) << "\" "; + } + if( system(cmd_ss.str().c_str()) ) + { + abort(); + } } void emit_box_drop_glue(::HIR::GenericPath p, const ::HIR::Struct& item) diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index b12673b1..26496aaf 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -70,7 +70,7 @@ TransList Trans_Enumerate_Main(const ::HIR::Crate& crate) // user entrypoint { - auto main_path = ::HIR::SimplePath("", {"main"}); + auto main_path = ::HIR::SimplePath(crate.m_crate_name, {"main"}); const auto& fcn = crate.get_function_by_path(sp, main_path); state.enum_fcn( main_path, fcn, {} ); @@ -80,120 +80,152 @@ TransList Trans_Enumerate_Main(const ::HIR::Crate& crate) } namespace { - void Trans_Enumerate_Public_Mod(EnumState& state, const ::HIR::Module& mod, ::HIR::SimplePath mod_path) + void Trans_Enumerate_Public_Mod(EnumState& state, ::HIR::Module& mod, ::HIR::SimplePath mod_path, bool is_visible) { const bool EMIT_ALL = true; - for(const auto& vi : mod.m_value_items) + for(auto& vi : mod.m_value_items) { - if( EMIT_ALL || vi.second->is_public ) { - TU_MATCHA( (vi.second->ent), (e), - (Import, - ), - (StructConstant, - ), - (StructConstructor, - ), - (Constant, - ), - (Static, + TU_MATCHA( (vi.second->ent), (e), + (Import, + ), + (StructConstant, + ), + (StructConstructor, + ), + (Constant, + ), + (Static, + if( EMIT_ALL || (is_visible && vi.second->is_public) ) + { //state.enum_static(mod_path + vi.first, *e); auto* ptr = state.rv.add_static(mod_path + vi.first); if(ptr) Trans_Enumerate_FillFrom(state, e, *ptr); - ), - (Function, - if( e.m_params.m_types.size() == 0 ) - { + } + ), + (Function, + if( e.m_params.m_types.size() == 0 ) + { + if( EMIT_ALL || (is_visible && vi.second->is_public) ) { state.enum_fcn(mod_path + vi.first, e, {}); } + } + else + { + const_cast<::HIR::Function&>(e).m_save_code = true; // TODO: If generic, enumerate concrete functions used - ) + } ) - } + ) } - for(const auto& ti : mod.m_mod_items) + for(auto& ti : mod.m_mod_items) { - if( (EMIT_ALL || ti.second->is_public) && ti.second->ent.is_Module() ) + if(auto* e = ti.second->ent.opt_Module() ) { - Trans_Enumerate_Public_Mod(state, ti.second->ent.as_Module(), mod_path + ti.first); + Trans_Enumerate_Public_Mod(state, *e, mod_path + ti.first, ti.second->is_public); } } } } /// Enumerate trans items for all public non-generic items (library crate) -TransList Trans_Enumerate_Public(const ::HIR::Crate& crate) +TransList Trans_Enumerate_Public(::HIR::Crate& crate) { static Span sp; EnumState state { crate }; - Trans_Enumerate_Public_Mod(state, crate.m_root_module, ::HIR::SimplePath("",{})); + Trans_Enumerate_Public_Mod(state, crate.m_root_module, ::HIR::SimplePath(crate.m_crate_name,{}), true); // Impl blocks StaticTraitResolve resolve { crate }; - for(const auto& impl : crate.m_trait_impls) + for(auto& impl : crate.m_trait_impls) { - if( impl.second.m_params.m_types.size() > 0 ) - continue ; const auto& impl_ty = impl.second.m_type; - auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.second.m_trait_args, nullptr); - - // Emit each method/static (in the trait itself) - const auto& trait = crate.get_trait_by_path(sp, impl.first); - for(const auto& vi : trait.m_values) + if( impl.second.m_params.m_types.size() == 0 ) { - if( vi.second.is_Constant() ) - ; - else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) - ; - else if( vi.first == "#vtable" ) - ; - else + auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.second.m_trait_args, nullptr); + + // Emit each method/static (in the trait itself) + const auto& trait = crate.get_trait_by_path(sp, impl.first); + for(const auto& vi : trait.m_values) { - // Check bounds before queueing for codegen - if( vi.second.is_Function() ) + if( vi.second.is_Constant() ) + ; + else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) + ; + else if( vi.first == "#vtable" ) + ; + else { - bool rv = true; - for(const auto& b : vi.second.as_Function().m_params.m_bounds) + // Check bounds before queueing for codegen + if( vi.second.is_Function() ) { - if( !b.is_TraitBound() ) continue; - const auto& be = b.as_TraitBound(); + bool rv = true; + for(const auto& b : vi.second.as_Function().m_params.m_bounds) + { + if( !b.is_TraitBound() ) continue; + const auto& be = b.as_TraitBound(); - auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); - auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); - for(auto& ty : b_tp_mono.m_path.m_params.m_types) { - resolve.expand_associated_types(sp, ty); - } - for(auto& assoc_bound : b_tp_mono.m_type_bounds) { - resolve.expand_associated_types(sp, assoc_bound.second); - } + auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); + auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); + for(auto& ty : b_tp_mono.m_path.m_params.m_types) { + resolve.expand_associated_types(sp, ty); + } + for(auto& assoc_bound : b_tp_mono.m_type_bounds) { + resolve.expand_associated_types(sp, assoc_bound.second); + } - rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { - return true; - }); + rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { + return true; + }); + if( !rv ) + break; + } if( !rv ) - break; + continue ; } - if( !rv ) - continue ; + auto p = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(impl.first, impl.second.m_trait_args.clone()), vi.first); + Trans_Enumerate_FillFrom_Path(state, p, {}); } - auto p = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(impl.first, impl.second.m_trait_args.clone()), vi.first); - Trans_Enumerate_FillFrom_Path(state, p, {}); + } + for(auto& m : impl.second.m_methods) + { + if( m.second.data.m_params.m_types.size() > 0 ) + m.second.data.m_save_code = true; + } + } + else + { + for(auto& m : impl.second.m_methods) + { + m.second.data.m_save_code = true; } } } - for(const auto& impl : crate.m_type_impls) + for(auto& impl : crate.m_type_impls) { - if( impl.m_params.m_types.size() > 0 ) - continue ; - - for(const auto& fcn : impl.m_methods) + if( impl.m_params.m_types.size() == 0 ) { - if( fcn.second.data.m_params.m_types.size() > 0 ) - continue ; - auto p = ::HIR::Path(impl.m_type.clone(), fcn.first); - Trans_Enumerate_FillFrom_Path(state, p, {}); + for(auto& fcn : impl.m_methods) + { + if( fcn.second.data.m_params.m_types.size() == 0 ) + { + auto p = ::HIR::Path(impl.m_type.clone(), fcn.first); + Trans_Enumerate_FillFrom_Path(state, p, {}); + } + else + { + fcn.second.data.m_save_code = true; + } + } + } + else + { + for(auto& m : impl.m_methods) + { + m.second.data.m_save_code = true; + } } } @@ -977,43 +1009,36 @@ namespace { ); EntPtr get_ent_simplepath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path) { - const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { - ASSERT_BUG(sp, crate.m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); - mod = &crate.m_ext_crates.at(path.m_crate_name)->m_root_module; - } - else { - mod = &crate.m_root_module; - } - for( unsigned int i = 0; i < path.m_components.size() - 1; i ++ ) + const ::HIR::ValueItem* vip; + if( path.m_components.size() > 1 ) { - const auto& pc = path.m_components[i]; - auto it = mod->m_mod_items.find( pc ); - if( it == mod->m_mod_items.end() ) { - BUG(sp, "Couldn't find component " << i << " of " << path); - } - TU_MATCH_DEF( ::HIR::TypeItem, (it->second->ent), (e2), + const auto& mi = crate.get_typeitem_by_path(sp, path, /*ignore_crate_name=*/false, /*ignore_last_node=*/true); + + TU_MATCH_DEF( ::HIR::TypeItem, (mi), (e), ( - BUG(sp, "Node " << i << " of path " << path << " wasn't a module"); + BUG(sp, "Node " << path.m_components.size()-1 << " of path " << path << " wasn't a module"); ), (Enum, - ASSERT_BUG(sp, i == path.m_components.size() - 2, "Enum found somewhere other than penultimate posiiton in " << path); // TODO: Check that this is a tuple variant return EntPtr::make_AutoGenerate({}); ), (Module, - mod = &e2; + auto it = e.m_value_items.find( path.m_components.back() ); + if( it == e.m_value_items.end() ) { + return EntPtr {}; + } + vip = &it->second->ent; ) ) } - - auto it = mod->m_value_items.find( path.m_components.back() ); - if( it == mod->m_value_items.end() ) { - return EntPtr {}; + else + { + vip = &crate.get_valitem_by_path(sp, path); } - TU_MATCH( ::HIR::ValueItem, (it->second->ent), (e), + + TU_MATCH( ::HIR::ValueItem, (*vip), (e), (Import, ), (StructConstant, @@ -1032,7 +1057,7 @@ namespace { return EntPtr { &e }; ) ) - BUG(sp, "Path " << path << " pointed to a invalid item - " << it->second->ent.tag_str()); + BUG(sp, "Path " << path << " pointed to a invalid item - " << vip->tag_str()); } EntPtr get_ent_fullpath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path, ::HIR::PathParams& impl_pp) { @@ -1481,13 +1506,13 @@ namespace { } ::HIR::Function* find_function_by_link_name(const ::HIR::Crate& crate, const char* name, ::HIR::SimplePath& out_path) { - if(auto rv = find_function_by_link_name(crate.m_root_module, {}, name, out_path)) + if(auto rv = find_function_by_link_name(crate.m_root_module, {crate.m_crate_name}, name, out_path)) return rv; for(const auto& e_crate : crate.m_ext_crates) { - if(auto rv = find_function_by_link_name(e_crate.second->m_root_module, {}, name, out_path)) + if(auto rv = find_function_by_link_name(e_crate.second.m_data->m_root_module, {e_crate.first}, name, out_path)) { - out_path.m_crate_name = e_crate.first; + assert( out_path.m_crate_name == e_crate.first ); return rv; } } diff --git a/src/trans/main_bindings.hpp b/src/trans/main_bindings.hpp index f4ffff96..2029cb28 100644 --- a/src/trans/main_bindings.hpp +++ b/src/trans/main_bindings.hpp @@ -14,6 +14,7 @@ class Crate; } extern TransList Trans_Enumerate_Main(const ::HIR::Crate& crate); -extern TransList Trans_Enumerate_Public(const ::HIR::Crate& crate); +// NOTE: This also sets the saveout flags +extern TransList Trans_Enumerate_Public(::HIR::Crate& crate); extern void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, const TransList& list, bool is_executable); |