diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/deserialise.cpp | 1 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 1 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 36 | ||||
-rw-r--r-- | src/mir/mir.hpp | 1 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 2 | ||||
-rw-r--r-- | src/trans/monomorphise.cpp | 1 |
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) }); ) |