diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-10 22:13:02 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-10 22:13:02 +0800 |
commit | ac499f7f9eee32e751334e96d0d0bf2bb68b1b8f (patch) | |
tree | 3090cc482df4ab4d99f0c9a8ca50d12a68ec435c /src | |
parent | d395407fbd9f8a53276fbcc76fd5c61882426b9f (diff) | |
download | mrust-ac499f7f9eee32e751334e96d0d0bf2bb68b1b8f.tar.gz |
Trans - Slight handling of DST structs
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/deserialise.cpp | 1 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 1 | ||||
-rw-r--r-- | src/hir_conv/markings.cpp | 13 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 103 |
4 files changed, 103 insertions, 15 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 7d570b94..f6b624c7 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -547,6 +547,7 @@ namespace { BIT(1, m.has_a_deref) BIT(2, m.is_copy) #undef BIT + m.dst_type = static_cast< ::HIR::TraitMarkings::DstType>( m_in.read_tag() ); m.coerce_unsized_index = m_in.read_count( ); m.unsized_field = m_in.read_count( ); // TODO: auto_impls diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 54b61387..b4e7c6a2 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -810,6 +810,7 @@ namespace { #undef BIT m_out.write_u8(bitflag_1); + m_out.write_tag( static_cast<unsigned int>(m.dst_type) ); m_out.write_count( m.coerce_unsized_index ); m_out.write_count( m.unsized_field ); // TODO: auto_impls diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp index 7f2189dd..ca5f7ca7 100644 --- a/src/hir_conv/markings.cpp +++ b/src/hir_conv/markings.cpp @@ -61,8 +61,21 @@ public: if( str.m_params.m_types.at(te.binding).m_is_sized == false ) { str.m_markings.unsized_field = se.size() - 1; + str.m_markings.dst_type = ::HIR::TraitMarkings::DstType::Possible; } } + else if( last_field.m_data.is_Slice() ) + { + str.m_markings.dst_type = ::HIR::TraitMarkings::DstType::Slice; + } + else if( last_field.m_data.is_TraitObject() ) + { + str.m_markings.dst_type = ::HIR::TraitMarkings::DstType::TraitObject; + } + else + { + str.m_markings.dst_type = ::HIR::TraitMarkings::DstType::None; + } } ) ) diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index e5a97f85..7951bb31 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -18,6 +18,12 @@ namespace { class CodeGenerator_C: public CodeGenerator { + enum class MetadataType { + None, + Slice, + TraitObject, + }; + const ::HIR::Crate& m_crate; ::StaticTraitResolve m_resolve; ::std::ofstream m_of; @@ -38,7 +44,6 @@ namespace { << "typedef uint32_t CHAR;\n" << "typedef struct { } tUNIT;\n" << "typedef struct { } tBANG;\n" - << "typedef struct { char* PTR; size_t META; } STR_PTR;\n" << "typedef struct { void* PTR; size_t META; } SLICE_PTR;\n" << "typedef struct { void* PTR; void* META; } TRAITOBJ_PTR;\n" << "\n"; @@ -414,11 +419,13 @@ namespace { TU_IFLET(::MIR::LValue, ve.val, Deref, e, ::HIR::TypeRef tmp; const auto& ty = mir_res.get_lvalue_type(tmp, ve.val); // NOTE: Checks the result of the deref - if( is_dst(ty) ) { + if( metadata_type(ty) != MetadataType::None ) { emit_lvalue(*e.val); special = true; } ) + // TODO: Magic for taking a &-ptr to unsized field of a struct. + // - Needs to get metadata from bottom-level pointer. if( !special ) { m_of << "& "; emit_lvalue(ve.val); @@ -691,9 +698,33 @@ namespace { m_of << Trans_Mangle(e); ), (Field, - // TODO: Also used for indexing - emit_lvalue(*e.val); - m_of << "._" << e.field_index; + ::HIR::TypeRef tmp; + const auto& ty = m_mir_res->get_lvalue_type(tmp, *e.val); + if( ty.m_data.is_Slice() ) { + m_of << "(("; emit_ctype(*ty.m_data.as_Slice().inner); m_of << "*)"; + emit_lvalue(*e.val); + m_of << ".DATA)[" << e.field_index << "]"; + } + else if( ty.m_data.is_Array() ) { + emit_lvalue(*e.val); + m_of << "[" << e.field_index << "]"; + } + else if( e.val->is_Deref() ) { + auto dst_type = metadata_type(ty); + if( dst_type != MetadataType::None ) + { + m_of << "(("; emit_ctype(ty); m_of << "*)"; emit_lvalue(*e.val->as_Deref().val); m_of << ".PTR)->_" << e.field_index; + } + else + { + emit_lvalue(*e.val); + m_of << "._" << e.field_index; + } + } + else { + emit_lvalue(*e.val); + m_of << "._" << e.field_index; + } ), (Deref, m_of << "(*"; @@ -828,21 +859,63 @@ namespace { ) } - void emit_ctype_ptr(const ::HIR::TypeRef& inner_ty, ::FmtLambda inner) { - if( inner_ty == ::HIR::CoreType::Str ) { - m_of << "STR_PTR " << inner; + MetadataType metadata_type(const ::HIR::TypeRef& ty) + { + if( ty == ::HIR::CoreType::Str || ty.m_data.is_Slice() ) { + return MetadataType::Slice; } - else if( inner_ty.m_data.is_TraitObject() ) { - m_of << "TRAITOBJ_PTR " << inner; + else if( ty.m_data.is_TraitObject() ) { + return MetadataType::TraitObject; } - else if( inner_ty.m_data.is_Slice() ) { - m_of << "SLICE_PTR " << inner; + else if( ty.m_data.is_Path() ) + { + const ::HIR::TraitMarkings* markings; + TU_MATCH_DEF( ::HIR::TypeRef::TypePathBinding, (ty.m_data.as_Path().binding), (tpb), + ( + BUG(Span(), "Unbound/opaque path in trans - " << ty); + ), + (Struct, markings = &tpb->m_markings; ), + (Union, markings = &tpb->m_markings; ), + (Enum, markings = &tpb->m_markings; ) + ) + switch( markings->dst_type ) + { + case ::HIR::TraitMarkings::DstType::None: + return MetadataType::None; + case ::HIR::TraitMarkings::DstType::Possible: + // TODO: How to figure out? + //TODO(Span(), "Determine DST type when ::Possible - " << ty); + return MetadataType::None; + case ::HIR::TraitMarkings::DstType::Slice: + return MetadataType::Slice; + case ::HIR::TraitMarkings::DstType::TraitObject: + return MetadataType::TraitObject; + } + throw ""; } - else if( inner_ty.m_data.is_Array() ) { + else { + return MetadataType::None; + } + } + + void emit_ctype_ptr(const ::HIR::TypeRef& inner_ty, ::FmtLambda inner) { + if( inner_ty.m_data.is_Array() ) { emit_ctype(inner_ty, FMT_CB(ss, ss << "(*" << inner << ")";)); } - else { - emit_ctype(inner_ty, FMT_CB(ss, ss << "*" << inner;)); + else + { + switch( metadata_type(inner_ty) ) + { + case MetadataType::None: + emit_ctype(inner_ty, FMT_CB(ss, ss << "*" << inner;)); + break; + case MetadataType::Slice: + m_of << "SLICE_PTR " << inner; + break; + case MetadataType::TraitObject: + m_of << "TRAITOBJ_PTR " << inner; + break; + } } } |