summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp1
-rw-r--r--src/hir/serialise.cpp1
-rw-r--r--src/mir/from_hir.cpp36
-rw-r--r--src/mir/mir.hpp1
-rw-r--r--src/trans/codegen_c.cpp2
-rw-r--r--src/trans/monomorphise.cpp1
6 files changed, 42 insertions, 0 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index e4fc6bc1..e3009cfc 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -380,6 +380,7 @@ namespace {
})
_(Struct, {
deserialise_genericpath(),
+ static_cast<unsigned int>( m_in.read_count() ),
deserialise_vec_c< ::MIR::LValue>([&](){ return deserialise_mir_lvalue(); })
})
#undef _
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index a1b8924a..30ce1bd4 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -591,6 +591,7 @@ namespace {
),
(Struct,
serialise_genericpath(e.path);
+ m_out.write_count(e.variant_idx);
serialise_vec(e.vals);
)
)
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index f4c119bb..4792d793 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -1322,6 +1322,7 @@ namespace {
void visit(::HIR::ExprNode_TupleVariant& node) override
{
+ const Span& sp = node.span();
TRACE_FUNCTION_F("_TupleVariant");
::std::vector< ::MIR::LValue> values;
values.reserve( node.m_args.size() );
@@ -1331,8 +1332,23 @@ namespace {
values.push_back( m_builder.get_result_in_lvalue(arg->span(), arg->m_res_type) );
}
+ unsigned int variant_index = ~0u;
+ if( !node.m_is_struct )
+ {
+ // Get the variant index from the enum.
+ auto enum_path = node.m_path.m_path;
+ enum_path.m_components.pop_back();
+ const auto& var_name = node.m_path.m_path.m_components.back();
+ const auto& enm = m_builder.crate().get_enum_by_path(sp, enum_path);
+ auto var_it = ::std::find_if(enm.m_variants.begin(), enm.m_variants.end(), [&](const auto& x){ return x.first == var_name; });
+ ASSERT_BUG(sp, var_it != enm.m_variants.end(), "Variant " << node.m_path.m_path << " isn't present");
+
+ variant_index = var_it - enm.m_variants.begin();
+ }
+
m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({
node.m_path.clone(),
+ variant_index,
mv$(values)
}) );
}
@@ -1539,9 +1555,24 @@ namespace {
}
void visit(::HIR::ExprNode_UnitVariant& node) override
{
+ const Span& sp = node.span();
TRACE_FUNCTION_F("_UnitVariant");
+ unsigned int variant_index = ~0u;
+ if( !node.m_is_struct )
+ {
+ // Get the variant index from the enum.
+ auto enum_path = node.m_path.m_path;
+ enum_path.m_components.pop_back();
+ const auto& var_name = node.m_path.m_path.m_components.back();
+ const auto& enm = m_builder.crate().get_enum_by_path(sp, enum_path);
+ auto var_it = ::std::find_if(enm.m_variants.begin(), enm.m_variants.end(), [&](const auto& x){ return x.first == var_name; });
+ ASSERT_BUG(sp, var_it != enm.m_variants.end(), "Variant " << node.m_path.m_path << " isn't present");
+
+ variant_index = var_it - enm.m_variants.begin();
+ }
m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({
node.m_path.clone(),
+ variant_index,
{}
}) );
}
@@ -1585,6 +1616,7 @@ namespace {
// TODO: Why is this still a PathValue?
m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({
pe.clone(),
+ ~0u,
{}
}) );
),
@@ -1703,6 +1735,7 @@ namespace {
base_val = m_builder.get_result_in_lvalue(node.m_base_value->span(), node.m_base_value->m_res_type);
}
+ unsigned int variant_index = ~0u;
const ::HIR::t_struct_fields* fields_ptr = nullptr;
TU_MATCH(::HIR::TypeRef::TypePathBinding, (node.m_res_type.m_data.as_Path().binding), (e),
(Unbound, ),
@@ -1712,6 +1745,7 @@ namespace {
const auto& enm = *e;
auto it = ::std::find_if(enm.m_variants.begin(), enm.m_variants.end(), [&](const auto&v)->auto{ return v.first == var_name; });
assert(it != enm.m_variants.end());
+ variant_index = it - enm.m_variants.begin();
fields_ptr = &it->second.as_Struct();
),
(Union,
@@ -1753,6 +1787,7 @@ namespace {
m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({
node.m_path.clone(),
+ variant_index,
mv$(values)
}) );
}
@@ -1833,6 +1868,7 @@ namespace {
m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({
node.m_obj_path.clone(),
+ ~0u,
mv$(vals)
}) );
}
diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp
index c01dcbd7..3215f9fc 100644
--- a/src/mir/mir.hpp
+++ b/src/mir/mir.hpp
@@ -155,6 +155,7 @@ TAGGED_UNION(RValue, Use,
// Create a new instance of a struct (or enum)
(Struct, struct {
::HIR::GenericPath path;
+ unsigned int variant_idx; // if ~0, it's a struct
::std::vector<LValue> vals;
})
);
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 9e0184bf..b429c8a8 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -460,6 +460,8 @@ namespace {
for(unsigned int j = 0; j < ve.vals.size(); j ++) {
if( j != 0 ) m_of << ";\n\t";
emit_lvalue(e.dst);
+ if(ve.variant_idx != ~0u)
+ m_of << ".DATA.var_" << ve.variant_idx;
m_of << "._" << j << " = ";
emit_lvalue(ve.vals[j]);
}
diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp
index b47ad15d..34eb2e1a 100644
--- a/src/trans/monomorphise.cpp
+++ b/src/trans/monomorphise.cpp
@@ -207,6 +207,7 @@ namespace {
(Struct,
rval = ::MIR::RValue::make_Struct({
params.monomorph(crate, se.path),
+ se.variant_idx,
monomorph_LValue_list(crate, params, se.vals)
});
)