summaryrefslogtreecommitdiff
path: root/src/trans/codegen_c.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-10 22:13:02 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-10 22:13:02 +0800
commitac499f7f9eee32e751334e96d0d0bf2bb68b1b8f (patch)
tree3090cc482df4ab4d99f0c9a8ca50d12a68ec435c /src/trans/codegen_c.cpp
parentd395407fbd9f8a53276fbcc76fd5c61882426b9f (diff)
downloadmrust-ac499f7f9eee32e751334e96d0d0bf2bb68b1b8f.tar.gz
Trans - Slight handling of DST structs
Diffstat (limited to 'src/trans/codegen_c.cpp')
-rw-r--r--src/trans/codegen_c.cpp103
1 files changed, 88 insertions, 15 deletions
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;
+ }
}
}