summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp3
-rw-r--r--src/hir/from_ast.cpp23
-rw-r--r--src/hir/hir.cpp15
-rw-r--r--src/hir/hir.hpp4
-rw-r--r--src/hir/serialise.cpp1
-rw-r--r--src/trans/target.cpp136
-rw-r--r--src/trans/target.hpp13
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);