diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-02-19 22:34:28 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-02-19 22:34:28 +0800 |
commit | 4242a60c7f5c6d425b1221b92cfc11d3d34dcdd7 (patch) | |
tree | e2dd914619f687e76a7acc0520a15a4d60fcb955 | |
parent | 82cce9cf1984fcedbd17c45fea50122a3c1ad378 (diff) | |
download | mrust-4242a60c7f5c6d425b1221b92cfc11d3d34dcdd7.tar.gz |
Trans - Conditionally emit struct/tuple constructor wrappers
-rw-r--r-- | src/trans/codegen.cpp | 30 | ||||
-rw-r--r-- | src/trans/codegen.hpp | 3 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 142 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 1 |
4 files changed, 119 insertions, 57 deletions
diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index 8b34cda3..6a581d93 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -10,6 +10,7 @@ #include <hir/hir.hpp> #include <mir/mir.hpp> #include <mir/operations.hpp> +#include <algorithm> #include "codegen.hpp" #include "monomorphise.hpp" @@ -51,6 +52,35 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const { codegen->emit_type_id(ty); } + // Emit required constructor methods (and other wrappers) + for(const auto& path : list.m_constructors) + { + // Get the item type + // - Function (must be an intrinsic) + // - Struct (must be a tuple struct) + // - Enum variant (must be a tuple variant) + const ::HIR::Module* mod_ptr = nullptr; + if(path.m_path.m_components.size() > 1) + { + const auto& nse = crate.get_typeitem_by_path(sp, path.m_path, false, true); + if(const auto* e = nse.opt_Enum()) + { + auto it = ::std::find_if(e->m_variants.begin(), e->m_variants.end(), [&](const auto& x){ return x.first == path.m_path.m_components.back(); }); + auto var_idx = it - e->m_variants.begin(); + codegen->emit_constructor_enum(sp, path, *e, var_idx); + continue ; + } + mod_ptr = &nse.as_Module(); + } + else + { + mod_ptr = &crate.get_mod_by_path(sp, path.m_path, true); + } + + // Not an enum, currently must be a struct + const auto& te = mod_ptr->m_mod_items.at(path.m_path.m_components.back())->ent; + codegen->emit_constructor_struct(sp, path, te.as_Struct()); + } // 2. Emit function prototypes for(const auto& ent : list.m_functions) diff --git a/src/trans/codegen.hpp b/src/trans/codegen.hpp index 3e936361..b317e632 100644 --- a/src/trans/codegen.hpp +++ b/src/trans/codegen.hpp @@ -40,6 +40,9 @@ public: virtual void emit_union(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Union& item) {} virtual void emit_enum(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Enum& item) {} + virtual void emit_constructor_enum(const Span& sp, const ::HIR::GenericPath& path, const ::HIR::Enum& item, size_t var_idx) {} + virtual void emit_constructor_struct(const Span& sp, const ::HIR::GenericPath& path, const ::HIR::Struct& item) {} + virtual void emit_vtable(const ::HIR::Path& p, const ::HIR::Trait& trait) {} virtual void emit_static_ext(const ::HIR::Path& p, const ::HIR::Static& item, const Trans_Params& params) {} diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 56607e8c..3ae69ba7 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -398,30 +398,6 @@ namespace { ) ) m_of << "};\n"; - // Crate constructor function - if( !has_unsized ) - { - TU_IFLET(::HIR::Struct::Data, item.m_data, Tuple, e, - m_of << "struct s_" << Trans_Mangle(p) << " " << Trans_Mangle(p) << "("; - for(unsigned int i = 0; i < e.size(); i ++) - { - if(i != 0) - m_of << ", "; - emit_ctype( monomorph(e[i].ent), FMT_CB(ss, ss << "_" << i;) ); - } - m_of << ") {\n"; - m_of << "\tstruct s_" << Trans_Mangle(p) << " rv = {"; - for(unsigned int i = 0; i < e.size(); i ++) - { - if(i != 0) - m_of << ","; - m_of << "\n\t\t_" << i; - } - m_of << "\n\t\t};\n"; - m_of << "\treturn rv;\n"; - m_of << "}\n"; - ) - } auto struct_ty = ::HIR::TypeRef(p.clone(), &item); auto drop_glue_path = ::HIR::Path(struct_ty.clone(), "#drop_glue"); @@ -608,13 +584,6 @@ namespace { m_of << "struct e_" << Trans_Mangle(p) << " {\n"; m_of << "\t"; emit_ctype(data_type, FMT_CB(s, s << "_0";)); m_of << ";\n"; m_of << "};\n"; - - m_of << "struct e_" << Trans_Mangle(p) << " " << Trans_Mangle(::HIR::GenericPath(p.m_path + data_var.first, p.m_params.clone())) << "("; - emit_ctype( data_type, FMT_CB(ss, ss << "_0";) ); - m_of << ") {\n"; - m_of << "\tstruct e_" << Trans_Mangle(p) << " rv = { ._0 = _0 };\n"; - m_of << "\treturn rv;\n"; - m_of << "}\n"; } else if( item.m_repr != ::HIR::Enum::Repr::Rust || ::std::all_of(item.m_variants.begin(), item.m_variants.end(), [](const auto& x){return x.second.is_Unit() || x.second.is_Value();}) ) { @@ -677,32 +646,6 @@ namespace { } m_of << "\t} DATA;\n"; m_of << "};\n"; - - // Constructors for tuple variants - for(unsigned int var_idx = 0; var_idx < item.m_variants.size(); var_idx ++) - { - const auto& var = item.m_variants[var_idx]; - TU_IFLET(::HIR::Enum::Variant, var.second, Tuple, e, - m_of << "struct e_" << Trans_Mangle(p) << " " << Trans_Mangle(::HIR::GenericPath(p.m_path + var.first, p.m_params.clone())) << "("; - for(unsigned int i = 0; i < e.size(); i ++) - { - if(i != 0) - m_of << ", "; - emit_ctype( monomorph(e[i].ent), FMT_CB(ss, ss << "_" << i;) ); - } - m_of << ") {\n"; - m_of << "\tstruct e_" << Trans_Mangle(p) << " rv = { .TAG = " << var_idx << ", .DATA = {.var_" << var_idx << " = {"; - for(unsigned int i = 0; i < e.size(); i ++) - { - if(i != 0) - m_of << ","; - m_of << "\n\t\t_" << i; - } - m_of << "\n\t\t}}};\n"; - m_of << "\treturn rv;\n"; - m_of << "}\n"; - ) - } } // --- @@ -794,6 +737,91 @@ namespace { } } + void emit_constructor_enum(const Span& sp, const ::HIR::GenericPath& path, const ::HIR::Enum& item, size_t var_idx) override + { + TRACE_FUNCTION_F(path << " var_idx=" << var_idx); + ::HIR::TypeRef tmp; + auto monomorph = [&](const auto& x)->const auto& { + if( monomorphise_type_needed(x) ) { + tmp = monomorphise_type(sp, item.m_params, path.m_params, x); + m_resolve.expand_associated_types(sp, tmp); + return tmp; + } + else { + return x; + } + }; + + auto p = path.clone(); + p.m_path.m_components.pop_back(); + const auto& var = item.m_variants[var_idx]; + ASSERT_BUG(sp, var.second.is_Tuple(), ""); + const auto& e = var.second.as_Tuple(); + + + m_of << "struct e_" << Trans_Mangle(p) << " " << Trans_Mangle(path) << "("; + for(unsigned int i = 0; i < e.size(); i ++) + { + if(i != 0) + m_of << ", "; + emit_ctype( monomorph(e[i].ent), FMT_CB(ss, ss << "_" << i;) ); + } + m_of << ") {\n"; + auto it = m_enum_repr_cache.find(p); + if( it != m_enum_repr_cache.end() ) + { + m_of << "\tstruct e_" << Trans_Mangle(p) << " rv = { ._0 = _0 };\n"; + } + else + { + m_of << "\tstruct e_" << Trans_Mangle(p) << " rv = { .TAG = " << var_idx << ", .DATA = {.var_" << var_idx << " = {"; + for(unsigned int i = 0; i < e.size(); i ++) + { + if(i != 0) + m_of << ","; + m_of << "\n\t\t_" << i; + } + m_of << "\n\t\t}}};\n"; + } + m_of << "\treturn rv;\n"; + m_of << "}\n"; + } + void emit_constructor_struct(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Struct& item) override + { + TRACE_FUNCTION_F(p); + ::HIR::TypeRef tmp; + auto monomorph = [&](const auto& x)->const auto& { + if( monomorphise_type_needed(x) ) { + tmp = monomorphise_type(sp, item.m_params, p.m_params, x); + m_resolve.expand_associated_types(sp, tmp); + return tmp; + } + else { + return x; + } + }; + // Crate constructor function + const auto& e = item.m_data.as_Tuple(); + m_of << "struct s_" << Trans_Mangle(p) << " " << Trans_Mangle(p) << "("; + for(unsigned int i = 0; i < e.size(); i ++) + { + if(i != 0) + m_of << ", "; + emit_ctype( monomorph(e[i].ent), FMT_CB(ss, ss << "_" << i;) ); + } + m_of << ") {\n"; + m_of << "\tstruct s_" << Trans_Mangle(p) << " rv = {"; + for(unsigned int i = 0; i < e.size(); i ++) + { + if(i != 0) + m_of << ","; + m_of << "\n\t\t_" << i; + } + m_of << "\n\t\t};\n"; + m_of << "\treturn rv;\n"; + m_of << "}\n"; + } + void emit_static_ext(const ::HIR::Path& p, const ::HIR::Static& item, const Trans_Params& params) override { ::MIR::TypeResolve top_mir_res { sp, m_resolve, FMT_CB(ss, ss << "extern static " << p;), ::HIR::TypeRef(), {}, *(::MIR::Function*)nullptr }; diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 6a44240c..8b9fd93b 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -1283,6 +1283,7 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co { // Leave generation of struct/enum constructors to codgen // TODO: Add to a list of required constructors + state.rv.m_constructors.insert( mv$(path_mono.m_data.as_Generic()) ); } // - <T as U>::#vtable else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().item == "#vtable" ) |