summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-02-19 22:34:28 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-02-19 22:34:28 +0800
commit4242a60c7f5c6d425b1221b92cfc11d3d34dcdd7 (patch)
treee2dd914619f687e76a7acc0520a15a4d60fcb955
parent82cce9cf1984fcedbd17c45fea50122a3c1ad378 (diff)
downloadmrust-4242a60c7f5c6d425b1221b92cfc11d3d34dcdd7.tar.gz
Trans - Conditionally emit struct/tuple constructor wrappers
-rw-r--r--src/trans/codegen.cpp30
-rw-r--r--src/trans/codegen.hpp3
-rw-r--r--src/trans/codegen_c.cpp142
-rw-r--r--src/trans/enumerate.cpp1
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" )