diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-12-31 16:28:33 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-12-31 16:28:33 +0800 |
commit | 3aef468f515a05fcfd9a549e46f2991501a966d6 (patch) | |
tree | 844696c363fb289220ad806c0fd864bc960398bf | |
parent | d5c10a7ea1cbd305c9072999a6cea8e6fefb4d60 (diff) | |
download | mrust-3aef468f515a05fcfd9a549e46f2991501a966d6.tar.gz |
Codegen - Remove need for `-z muldefs`
-rw-r--r-- | src/expand/crate_tags.cpp | 37 | ||||
-rw-r--r-- | src/main.cpp | 50 | ||||
-rw-r--r-- | src/trans/codegen.cpp | 1 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 29 |
4 files changed, 100 insertions, 17 deletions
diff --git a/src/expand/crate_tags.cpp b/src/expand/crate_tags.cpp index ca5a98ce..e99f1aa2 100644 --- a/src/expand/crate_tags.cpp +++ b/src/expand/crate_tags.cpp @@ -52,7 +52,44 @@ public: } }; +class Decorator_Allocator: + public ExpandDecorator +{ +public: + AttrStage stage() const override { return AttrStage::Pre; } + + void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate) const override { + // TODO: Check for an existing allocator crate + crate.m_lang_items.insert(::std::make_pair( "mrustc-allocator", AST::Path("",{}) )); + } +}; +class Decorator_PanicRuntime: + public ExpandDecorator +{ +public: + AttrStage stage() const override { return AttrStage::Pre; } + + void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate) const override { + // TODO: Check for an existing panic_runtime crate + crate.m_lang_items.insert(::std::make_pair( "mrustc-panic_runtime", AST::Path("",{}) )); + } +}; +class Decorator_NeedsPanicRuntime: + public ExpandDecorator +{ +public: + AttrStage stage() const override { return AttrStage::Pre; } + + void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate) const override { + crate.m_lang_items.insert(::std::make_pair( "mrustc-needs_panic_runtime", AST::Path("",{}) )); + } +}; + STATIC_DECORATOR("crate_type", Decorator_CrateType) STATIC_DECORATOR("crate_name", Decorator_CrateName) +STATIC_DECORATOR("allocator", Decorator_Allocator) +STATIC_DECORATOR("panic_runtime", Decorator_PanicRuntime) +STATIC_DECORATOR("needs_panic_runtime", Decorator_NeedsPanicRuntime) + diff --git a/src/main.cpp b/src/main.cpp index e6220fe6..36fa106e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -328,19 +328,55 @@ int main(int argc, char *argv[]) // Allocator and panic strategies CompilePhaseV("Implicit Crates", [&]() { + if( params.test_harness ) + { + crate.load_extern_crate(Span(), "test"); + } if( crate.m_crate_type == ::AST::Crate::Type::Executable || params.test_harness || crate.m_crate_type == ::AST::Crate::Type::ProcMacro ) { - // TODO: Detect if an allocator crate is already present. - crate.load_extern_crate(Span(), "alloc_system"); - crate.load_extern_crate(Span(), "panic_abort"); + bool allocator_crate_loaded = false; + bool panic_runtime_loaded = false; + bool panic_runtime_needed = false; + for(const auto& ec : crate.m_extern_crates) + { + ::std::ostringstream ss; + for(const auto& e : ec.second.m_hir->m_lang_items) + ss << e << ","; + DEBUG("Looking at lang items from " << ec.first << " : " << ss.str()); + if(ec.second.m_hir->m_lang_items.count("mrustc-allocator")) + { + if( allocator_crate_loaded ) { + // TODO: Emit an error because there's multiple allocators loaded + } + allocator_crate_loaded = true; + } + if(ec.second.m_hir->m_lang_items.count("mrustc-panic_runtime")) + { + if( panic_runtime_loaded ) { + // TODO: Emit an error because there's multiple allocators loaded + } + panic_runtime_loaded = true; + } + if(ec.second.m_hir->m_lang_items.count("mrustc-needs_panic_runtime")) + { + panic_runtime_needed = true; + } + } + if( !allocator_crate_loaded ) + { + crate.load_extern_crate(Span(), "alloc_system"); + } + + if( panic_runtime_needed && !panic_runtime_loaded ) + { + // TODO: Get a panic method from the command line + // - Fall back to abort by default, because mrustc doesn't do unwinding yet. + crate.load_extern_crate(Span(), "panic_abort"); + } // - `mrustc-main` lang item default crate.m_lang_items.insert(::std::make_pair( ::std::string("mrustc-main"), ::AST::Path("", {AST::PathNode("main")}) )); } - if( params.test_harness ) - { - crate.load_extern_crate(Span(), "test"); - } }); // Resolve names to be absolute names (include references to the relevant struct/global/function) diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index a705c67b..b3244072 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -87,6 +87,7 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const DEBUG("FUNCTION " << ent.first); assert( ent.second->ptr ); const auto& fcn = *ent.second->ptr; + // Extern if there isn't any HIR bool is_extern = ! static_cast<bool>(fcn.m_code); if( fcn.m_code.m_mir ) { codegen->emit_function_proto(ent.first, fcn, ent.second->pp, is_extern); diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index f3274d68..393aba72 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -490,7 +490,6 @@ namespace { { args.push_back("-l"); args.push_back(path.c_str()); } - args.push_back("-z"); args.push_back("muldefs"); args.push_back("-Wl,--gc-sections"); } else @@ -760,6 +759,10 @@ namespace { { ::MIR::TypeResolve top_mir_res { sp, m_resolve, FMT_CB(ss, ss << "struct " << p;), ::HIR::TypeRef(), {}, *(::MIR::Function*)nullptr }; m_mir_res = &top_mir_res; + bool is_vtable; { + const auto& lc = p.m_path.m_components.back(); + is_vtable = (lc.size() > 7 && ::std::strcmp(lc.c_str() + lc.size() - 7, "#vtable") == 0); + }; TRACE_FUNCTION_F(p); ::HIR::TypeRef tmp; @@ -796,11 +799,9 @@ namespace { m_of << "struct s_" << Trans_Mangle(p) << " {\n"; // HACK: For vtables, insert the alignment and size at the start + if(is_vtable) { - const auto& lc = p.m_path.m_components.back(); - if( lc.size() > 7 && ::std::strcmp(lc.c_str() + lc.size() - 7, "#vtable") == 0 ) { - m_of << "\tVTABLE_HDR hdr;\n"; - } + m_of << "\tVTABLE_HDR hdr;\n"; } TU_MATCHA( (item.m_data), (e), @@ -1222,7 +1223,7 @@ namespace { const auto& e = str.m_data.as_Tuple(); - m_of << "struct e_" << Trans_Mangle(p) << " " << Trans_Mangle(path) << "("; + m_of << "static struct e_" << Trans_Mangle(p) << " " << Trans_Mangle(path) << "("; for(unsigned int i = 0; i < e.size(); i ++) { if(i != 0) @@ -1282,7 +1283,7 @@ namespace { }; // Crate constructor function const auto& e = item.m_data.as_Tuple(); - m_of << "struct s_" << Trans_Mangle(p) << " " << Trans_Mangle(p) << "("; + m_of << "static struct s_" << Trans_Mangle(p) << " " << Trans_Mangle(p) << "("; for(unsigned int i = 0; i < e.size(); i ++) { if(i != 0) @@ -1683,10 +1684,13 @@ namespace { auto fcn_p = p.clone(); fcn_p.m_data.as_UfcsKnown().item = call_fcn_name; fcn_p.m_data.as_UfcsKnown().trait.m_path = trait_name.clone(); - emit_ctype(*te->m_rettype); + auto arg_ty = ::HIR::TypeRef::new_unit(); for(const auto& ty : te->m_arg_types) arg_ty.m_data.as_Tuple().push_back( ty.clone() ); + + m_of << "static "; + emit_ctype(*te->m_rettype); m_of << " " << Trans_Mangle(fcn_p) << "("; emit_ctype(type, FMT_CB(ss, ss << "*ptr";)); m_of << ", "; emit_ctype(arg_ty, FMT_CB(ss, ss << "args";)); m_of << ") {\n"; m_of << "\treturn (*ptr)("; for(unsigned int i = 0; i < te->m_arg_types.size(); i++) @@ -1711,10 +1715,15 @@ namespace { const auto& vtable_ref = m_crate.get_struct_by_path(sp, vtable_sp); ::HIR::TypeRef vtable_ty( ::HIR::GenericPath(mv$(vtable_sp), mv$(vtable_params)), &vtable_ref ); - if( m_compiler == Compiler::Msvc ) + // Weak link for vtables + switch(m_compiler) { - // Weak link for vtables + case Compiler::Gcc: + m_of << "__attribute__((weak)) "; + break; + case Compiler::Msvc: m_of << "__declspec(selectany) "; + break; } emit_ctype(vtable_ty); |