diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/deserialise.cpp | 3 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 23 | ||||
-rw-r--r-- | src/hir/hir.cpp | 15 | ||||
-rw-r--r-- | src/hir/hir.hpp | 4 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 1 | ||||
-rw-r--r-- | src/trans/target.cpp | 136 | ||||
-rw-r--r-- | src/trans/target.hpp | 13 |
7 files changed, 37 insertions, 158 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index afce2fe4..9ce063b4 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -995,11 +995,12 @@ default: throw ""; } + auto align = static_cast<unsigned>(m_in.read_u64c()); auto markings = deserialise_markings(); auto str_markings = deserialise_str_markings(); return ::HIR::Struct { - mv$(params), repr, mv$(data), mv$(markings), mv$(str_markings) + mv$(params), repr, mv$(data), align, mv$(markings), mv$(str_markings) }; } ::HIR::Trait HirDeserialiser::deserialise_trait() diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index f5d841a7..23e722f4 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -894,31 +894,32 @@ namespace { const auto& repr_str = a.name(); if( repr_str == "C" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); - rv.m_repr = ::HIR::Struct::Repr::C; + if( rv.m_repr != ::HIR::Struct::Repr::Packed ) + { + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + rv.m_repr = ::HIR::Struct::Repr::C; + } } else if( repr_str == "packed" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust || rv.m_repr == ::HIR::Struct::Repr::C, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); rv.m_repr = ::HIR::Struct::Repr::Packed; } else if( repr_str == "simd" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); rv.m_repr = ::HIR::Struct::Repr::Simd; } else if( repr_str == "transparent" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); - // TODO: Mark so the C backend knows that it's supposed to be transparent - //rv.m_repr = ::HIR::Struct::Repr::Transparent; + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + rv.m_repr = ::HIR::Struct::Repr::Transparent; } else if( repr_str == "align" ) { //ASSERT_BUG(a.span(), a.has_string(), "#[repr(aligned)] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); - // TODO: Alignment repr - //rv.m_repr = ::HIR::Struct::Repr::Aligned; - //rv.m_align_size = ::std::stol(a.string()); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + rv.m_repr = ::HIR::Struct::Repr::Aligned; + //rv.m_forced_alignment = ::std::stol(a.string()); } else { TODO(a.span(), "Handle struct repr '" << repr_str << "'"); diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 475928a1..bd396df9 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -93,6 +93,21 @@ namespace HIR { ) return true; } + + ::std::ostream& operator<<(::std::ostream& os, const Struct::Repr& x) { + os << "repr("; + switch(x) + { + case Struct::Repr::Rust: os << "Rust"; break; + case Struct::Repr::C: os << "C"; break; + case Struct::Repr::Packed: os << "packed"; break; + case Struct::Repr::Simd: os << "simd"; break; + case Struct::Repr::Aligned: os << "align(?)"; break; + case Struct::Repr::Transparent: os << "transparent"; break; + } + os << ")"; + return os; + } } size_t HIR::Enum::find_variant(const ::std::string& name) const diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 33200e96..fc4a19e8 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -267,6 +267,8 @@ public: C, Packed, Simd, + Aligned, // Alignment stored elsewhere + Transparent, }; TAGGED_UNION(Data, Unit, (Unit, struct {}), @@ -277,10 +279,12 @@ public: GenericParams m_params; Repr m_repr; Data m_data; + unsigned m_forced_alignment = 0; TraitMarkings m_markings; StructMarkings m_struct_markings; }; +extern ::std::ostream& operator<<(::std::ostream& os, const Struct::Repr& x); class Union { public: diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 50da4453..c3a27998 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -975,6 +975,7 @@ ) ) + m_out.write_u64c(item.m_forced_alignment); serialise(item.m_markings); serialise(item.m_struct_markings); } diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 121a9134..dccc566d 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -517,139 +517,6 @@ void Target_SetCfg(const ::std::string& target_name) }); } -namespace { - // Returns NULL when the repr can't be determined - ::std::unique_ptr<StructRepr> make_struct_repr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty) - { - TRACE_FUNCTION_F(ty); - ::std::vector<StructRepr::Ent> ents; - bool packed = false; - bool allow_sort = false; - if( const auto* te = ty.m_data.opt_Path() ) - { - const auto& str = *te->binding.as_Struct(); - auto monomorph_cb = monomorphise_type_get_cb(sp, nullptr, &te->path.m_data.as_Generic().m_params, nullptr); - auto monomorph = [&](const auto& tpl) { - auto rv = monomorphise_type_with(sp, tpl, monomorph_cb); - resolve.expand_associated_types(sp, rv); - return rv; - }; - TU_MATCHA( (str.m_data), (se), - (Unit, - ), - (Tuple, - unsigned int idx = 0; - for(const auto& e : se) - { - auto ty = monomorph(e.ent); - size_t size, align; - if( !Target_GetSizeAndAlignOf(sp, resolve, ty, size,align) ) - return nullptr; - if( size == SIZE_MAX ) - BUG(sp, "Unsized type in tuple struct"); - ents.push_back(StructRepr::Ent { idx++, size, align, mv$(ty) }); - } - ), - (Named, - unsigned int idx = 0; - for(const auto& e : se) - { - auto ty = monomorph(e.second.ent); - size_t size, align; - if( !Target_GetSizeAndAlignOf(sp, resolve, ty, size,align) ) - return nullptr; - if( size == SIZE_MAX ) - BUG(sp, "Unsized type in struct"); - ents.push_back(StructRepr::Ent { idx++, size, align, mv$(ty) }); - } - ) - ) - switch(str.m_repr) - { - case ::HIR::Struct::Repr::Packed: - packed = true; - TODO(sp, "make_struct_repr - repr(packed)"); // needs codegen to know to pack the structure - break; - case ::HIR::Struct::Repr::Simd: - case ::HIR::Struct::Repr::C: - // No sorting, no packing - break; - case ::HIR::Struct::Repr::Rust: - allow_sort = true; - break; - } - } - else if( const auto* te = ty.m_data.opt_Tuple() ) - { - unsigned int idx = 0; - for(const auto& t : *te) - { - size_t size, align; - if( !Target_GetSizeAndAlignOf(sp, resolve, t, size,align) ) - return nullptr; - if( size == SIZE_MAX ) - BUG(sp, "Unsized type in tuple"); - ents.push_back(StructRepr::Ent { idx++, size, align, t.clone() }); - } - } - else - { - BUG(sp, "Unexpected type in creating struct repr"); - } - - - if( allow_sort ) - { - // TODO: Sort by alignment then size (largest first) - // - Requires codegen to use this information - } - - StructRepr rv; - size_t cur_ofs = 0; - size_t max_align = 1; - for(auto& e : ents) - { - // Increase offset to fit alignment - if( !packed ) - { - while( cur_ofs % e.align != 0 ) - { - rv.ents.push_back({ ~0u, 1, 1, ::HIR::TypeRef( ::HIR::CoreType::U8 ) }); - cur_ofs ++; - } - } - max_align = ::std::max(max_align, e.align); - - rv.ents.push_back(mv$(e)); - cur_ofs += e.size; - } - if( !packed ) - { - while( cur_ofs % max_align != 0 ) - { - rv.ents.push_back({ ~0u, 1, 1, ::HIR::TypeRef( ::HIR::CoreType::U8 ) }); - cur_ofs ++; - } - } - return box$(rv); - } -} -const StructRepr* Target_GetStructRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty) -{ - // TODO: Thread safety - // Map of generic paths to struct representations. - static ::std::map<::HIR::TypeRef, ::std::unique_ptr<StructRepr>> s_cache; - - auto it = s_cache.find(ty); - if( it != s_cache.end() ) - { - return it->second.get(); - } - - auto ires = s_cache.insert(::std::make_pair( ty.clone(), make_struct_repr(sp, resolve, ty) )); - return ires.first->second.get(); -} - bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size, size_t& out_align) { TRACE_FUNCTION_FR(ty, "size=" << out_size << ", align=" << out_align); @@ -904,6 +771,9 @@ namespace { case ::HIR::Struct::Repr::Simd: // No sorting, no packing break; + case ::HIR::Struct::Repr::Aligned: + // TODO: Update the minimum alignment + case ::HIR::Struct::Repr::Transparent: case ::HIR::Struct::Repr::Rust: allow_sort = true; break; diff --git a/src/trans/target.hpp b/src/trans/target.hpp index b1ed9456..107d19e1 100644 --- a/src/trans/target.hpp +++ b/src/trans/target.hpp @@ -48,18 +48,6 @@ struct TargetSpec TargetArch m_arch; }; -struct StructRepr -{ - struct Ent { - unsigned int field_idx; - size_t size; - size_t align; - ::HIR::TypeRef ty; - }; - // List of types, including padding (indicated by a UINT_MAX field idx) - // Ordered as they would be emitted - ::std::vector<Ent> ents; -}; struct TypeRepr { size_t align = 0; @@ -107,7 +95,6 @@ extern void Target_ExportCurSpec(const ::std::string& filename); extern bool Target_GetSizeOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size); extern bool Target_GetAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_align); extern bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size, size_t& out_align); -extern const StructRepr* Target_GetStructRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& struct_ty); extern const TypeRepr* Target_GetTypeRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty); |