diff options
author | John Hodge <tpg@mutabah.net> | 2017-01-03 20:54:16 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-01-03 20:54:16 +0800 |
commit | 34f4df4b8fa19f2a73fb8603b290b21865bca37f (patch) | |
tree | 9616eba7b8e1b2793c3f32f1a78f714bc0883883 /src | |
parent | a25f03e36fc1deffb9deee1a16634b19d5cb677b (diff) | |
download | mrust-34f4df4b8fa19f2a73fb8603b290b21865bca37f.tar.gz |
Trans C - Enum variant constructor pointers
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/hir.cpp | 7 | ||||
-rw-r--r-- | src/hir/hir.hpp | 2 | ||||
-rw-r--r-- | src/mir/check.cpp | 17 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 54 |
4 files changed, 75 insertions, 5 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 8d519f41..7f4df952 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -609,9 +609,10 @@ const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path_opt(const char* name) return it->second; } -const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name) const +const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name, bool ignore_last_node) const { ASSERT_BUG(sp, path.m_components.size() > 0, "get_typeitem_by_path received invalid path - " << path); + 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 != "" ) { @@ -621,7 +622,7 @@ const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const else { mod = &this->m_root_module; } - for( unsigned int i = 0; i < path.m_components.size() - 1; i ++ ) + for( unsigned int i = 0; i < path.m_components.size() - (ignore_last_node ? 2 : 1); i ++ ) { const auto& pc = path.m_components[i]; auto it = mod->m_mod_items.find( pc ); @@ -635,7 +636,7 @@ const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const BUG(sp, "Node " << i << " of path " << path << " wasn't a module"); } } - auto it = mod->m_mod_items.find( path.m_components.back() ); + auto it = mod->m_mod_items.find( ignore_last_node ? path.m_components[path.m_components.size()-2] : path.m_components.back() ); if( it == mod->m_mod_items.end() ) { BUG(sp, "Could not find type name in " << path); } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 2f8c39bb..76e6cf81 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -427,7 +427,7 @@ public: const ::HIR::SimplePath& get_lang_item_path(const Span& sp, const char* name) const; const ::HIR::SimplePath& get_lang_item_path_opt(const char* name) const; - const ::HIR::TypeItem& get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name=false) const; + const ::HIR::TypeItem& get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name=false, bool ignore_last_node=false) const; const ::HIR::Trait& get_trait_by_path(const Span& sp, const ::HIR::SimplePath& path) const; const ::HIR::Struct& get_struct_by_path(const Span& sp, const ::HIR::SimplePath& path) const; const ::HIR::Union& get_union_by_path(const Span& sp, const ::HIR::SimplePath& path) const; diff --git a/src/mir/check.cpp b/src/mir/check.cpp index ad8c9613..d6fcb1b9 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -604,6 +604,23 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path // TODO: Check return type ), (MakeDst, + #if 0 + ::HIR::TypeRef tmp; + const auto& ty = state.get_lvalue_type(tmp, a.dst); + const ::HIR::TypeRef* ity_p = nullptr; + if( ty.m_data.is_Borrow() ) + ity_p = &*ty.m_data.as_Borrow().inner; + else if( ty.m_data.is_Pointer() ) + ity_p = &*ty.m_data.as_Pointer().inner; + else + MIR_BUG(state, "DstMeta requires a pointer as output, got " << ty); + auto meta = get_metadata_type(state.m_resolve, *ity_p); + if( meta == ::HIR::TypeRef() ) + { + MIR_BUG(state, "DstMeta requires a pointer to an unsized type as output, got " << ty); + } + #endif + // TODO: Check metadata type? ), (Tuple, // TODO: Check return type diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 83e2ab8a..de246232 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -454,6 +454,30 @@ namespace { m_of << "};\n"; // TODO: 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"; + ) + } // --- // - Drop Glue @@ -1119,7 +1143,35 @@ namespace { (ItemAddr, emit_lvalue(e.dst); m_of << " = "; - m_of << "&" << Trans_Mangle(c); + TU_MATCHA( (c.m_data), (pe), + (Generic, + if( pe.m_path.m_components.size() > 1 && m_crate.get_typeitem_by_path(sp, pe.m_path, false, true).is_Enum() ) + ; + else + { + const auto& vi = m_crate.get_valitem_by_path(sp, pe.m_path); + if( vi.is_Function() || vi.is_StructConstructor() ) + { + } + else + { + m_of << "&"; + } + } + ), + (UfcsUnknown, + MIR_BUG(*m_mir_res, "UfcsUnknown in trans " << c); + ), + (UfcsInherent, + // TODO: If the target is a function, don't emit the & + m_of << "&"; + ), + (UfcsKnown, + // TODO: If the target is a function, don't emit the & + m_of << "&"; + ) + ) + m_of << Trans_Mangle(c); ) ) ), |