diff options
author | John Hodge <tpg@ucc.asn.au> | 2018-06-03 14:57:05 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2018-06-03 14:57:05 +0800 |
commit | bf8f8b4b4a9fe273451be59f68acafbe61968b83 (patch) | |
tree | 82993550cb3c88de0edbd55d79e4ea8e8cefffac /src/trans/codegen_c.cpp | |
parent | 39b3cf53798683e496804f8322da2254b10850f4 (diff) | |
parent | a7fb27789a2b34543851d207120e2c0001ee9c27 (diff) | |
download | mrust-bf8f8b4b4a9fe273451be59f68acafbe61968b83.tar.gz |
Merge branch 'master' of https://github.com/thepowersgang/mrustc
Diffstat (limited to 'src/trans/codegen_c.cpp')
-rw-r--r-- | src/trans/codegen_c.cpp | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 5df20334..c30657bf 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -196,6 +196,7 @@ namespace { } m_options; ::std::vector< ::std::pair< ::HIR::GenericPath, const ::HIR::Struct*> > m_box_glue_todo; + ::std::set< ::HIR::TypeRef> m_emitted_fn_types; public: CodeGenerator_C(const ::HIR::Crate& crate, const ::std::string& outfile): m_crate(crate), @@ -204,7 +205,7 @@ namespace { m_outfile_path_c(outfile + ".c"), m_of(m_outfile_path_c) { - switch(Target_GetCurSpec().m_codegen_mode) + switch(Target_GetCurSpec().m_backend_c.m_codegen_mode) { case CodegenMode::Gnu11: m_compiler = Compiler::Gcc; @@ -302,7 +303,7 @@ namespace { << "\treturn ((v&0xFFFFFFFF) == 0 ? __builtin_ctz(v>>32) + 32 : __builtin_ctz(v));\n" << "}\n" ; - break; + break; case Compiler::Msvc: m_of << "static inline uint64_t __builtin_popcount(uint64_t v) {\n" @@ -510,6 +511,7 @@ namespace { emit_box_drop_glue( mv$(e.first), *e.second ); } + // TODO: Define this function in MIR. if( is_executable ) { m_of << "int main(int argc, const char* argv[]) {\n"; @@ -565,7 +567,7 @@ namespace { // - `gcc-${TRIPLE}` (if available) // - `gcc` as fallback { - ::std::string varname = "CC-" + Target_GetCurSpec().m_c_compiler; + ::std::string varname = "CC-" + Target_GetCurSpec().m_backend_c.m_c_compiler; if( getenv(varname.c_str()) ) { args.push_back( getenv(varname.c_str()) ); } @@ -574,12 +576,14 @@ namespace { } else { // TODO: Determine if the compiler can't be found, and fall back to `gcc` if that's the case - args.push_back( Target_GetCurSpec().m_c_compiler + "-gcc" ); + args.push_back( Target_GetCurSpec().m_backend_c.m_c_compiler + "-gcc" ); //args.push_back( "gcc" ); } } - args.push_back("-ffunction-sections"); - args.push_back("-pthread"); + for( const auto& a : Target_GetCurSpec().m_backend_c.m_compiler_opts ) + { + args.push_back( a.c_str() ); + } switch(opt.opt_level) { case 0: break; @@ -622,7 +626,10 @@ namespace { { args.push_back("-l"); args.push_back(path.c_str()); } - args.push_back("-Wl,--gc-sections"); + for( const auto& a : Target_GetCurSpec().m_backend_c.m_linker_opts ) + { + args.push_back( a.c_str() ); + } } else { @@ -631,8 +638,9 @@ namespace { break; case Compiler::Msvc: // TODO: Look up these paths in the registry and use CreateProcess instead of system + // - OR, run `vcvarsall` and get the required environment variables and PATH from it? args.push_back(detect_msvc().path_vcvarsall); - args.push_back( Target_GetCurSpec().m_c_compiler ); + args.push_back( Target_GetCurSpec().m_backend_c.m_c_compiler ); args.push_back("&"); args.push_back("cl.exe"); args.push_back("/nologo"); @@ -678,9 +686,9 @@ namespace { } args.push_back("kernel32.lib"); // Needed for Interlocked* - // Command-line specified linker search directories args.push_back("/link"); - //args.push_back("/verbose"); + + // Command-line specified linker search directories for(const auto& path : link_dirs ) { args.push_back(FMT("/LIBPATH:" << path)); @@ -818,6 +826,11 @@ namespace { } void emit_type_fn(const ::HIR::TypeRef& ty) { + if( m_emitted_fn_types.count(ty) ) { + return ; + } + m_emitted_fn_types.insert(ty.clone()); + const auto& te = ty.m_data.as_Function(); m_of << "typedef "; // TODO: ABI marker, need an ABI enum? @@ -1127,6 +1140,12 @@ namespace { m_of << ".PTR"; } } + else if( const auto* te = ty->m_data.opt_Pointer() ) + { + if( metadata_type(*te->inner) != MetadataType::None ) { + m_of << ".PTR"; + } + } } void emit_enum(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Enum& item) override @@ -3556,7 +3575,7 @@ namespace { #endif } - if( Target_GetCurSpec().m_c_compiler == "amd64" ) { + if( Target_GetCurSpec().m_backend_c.m_c_compiler == "amd64" ) { MIR_TODO(mir_res, "MSVC amd64 doesn't support inline assembly, need to have a transform for '" << e.tpl << "'"); } m_of << indent << "__asm {\n"; @@ -4664,6 +4683,11 @@ namespace { void emit_destructor_call(const ::MIR::LValue& slot, const ::HIR::TypeRef& ty, bool unsized_valid, unsigned indent_level) { + // If the type doesn't need dropping, don't try. + if( !m_resolve.type_needs_drop_glue(sp, ty) ) + { + return ; + } auto indent = RepeatLitStr { "\t", static_cast<int>(indent_level) }; TU_MATCHA( (ty.m_data), (te), // Impossible |