summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-12-31 16:28:33 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-12-31 16:28:33 +0800
commit3aef468f515a05fcfd9a549e46f2991501a966d6 (patch)
tree844696c363fb289220ad806c0fd864bc960398bf
parentd5c10a7ea1cbd305c9072999a6cea8e6fefb4d60 (diff)
downloadmrust-3aef468f515a05fcfd9a549e46f2991501a966d6.tar.gz
Codegen - Remove need for `-z muldefs`
-rw-r--r--src/expand/crate_tags.cpp37
-rw-r--r--src/main.cpp50
-rw-r--r--src/trans/codegen.cpp1
-rw-r--r--src/trans/codegen_c.cpp29
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);