summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-01-03 20:54:16 +0800
committerJohn Hodge <tpg@mutabah.net>2017-01-03 20:54:16 +0800
commit34f4df4b8fa19f2a73fb8603b290b21865bca37f (patch)
tree9616eba7b8e1b2793c3f32f1a78f714bc0883883 /src
parenta25f03e36fc1deffb9deee1a16634b19d5cb677b (diff)
downloadmrust-34f4df4b8fa19f2a73fb8603b290b21865bca37f.tar.gz
Trans C - Enum variant constructor pointers
Diffstat (limited to 'src')
-rw-r--r--src/hir/hir.cpp7
-rw-r--r--src/hir/hir.hpp2
-rw-r--r--src/mir/check.cpp17
-rw-r--r--src/trans/codegen_c.cpp54
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);
)
)
),