From ea32668e6ca82962d720ad9d7751a8e4339b09aa Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 28 Dec 2018 19:58:42 +0800 Subject: Trans Target - cfg for atomic comare-and-set (tied to atomic ptr) --- src/trans/target.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index f91b679a..121a9134 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -509,6 +509,7 @@ void Target_SetCfg(const ::std::string& target_name) if(s == "32") return g_target.m_arch.m_atomics.u32; if(s == "64") return g_target.m_arch.m_atomics.u64; if(s == "ptr") return g_target.m_arch.m_atomics.ptr; // Has an atomic pointer-sized value + if(s == "cas") return g_target.m_arch.m_atomics.ptr; // TODO: Atomic compare-and-set option return false; }); Cfg_SetValueCb("target_feature", [](const ::std::string& s) { -- cgit v1.2.3 From 28a48cfe2fde578219de5e15268348897c73b0d7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 29 Dec 2018 15:00:52 +0800 Subject: HIR - Add new struct reprs (mostly stubbed) - Also cleared out some dead code in target.cpp --- src/hir/deserialise.cpp | 3 +- src/hir/from_ast.cpp | 23 ++++---- src/hir/hir.cpp | 15 ++++++ src/hir/hir.hpp | 4 ++ src/hir/serialise.cpp | 1 + src/trans/target.cpp | 136 ++---------------------------------------------- src/trans/target.hpp | 13 ----- 7 files changed, 37 insertions(+), 158 deletions(-) (limited to 'src/trans/target.cpp') 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(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 make_struct_repr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty) - { - TRACE_FUNCTION_F(ty); - ::std::vector 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> 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 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); -- cgit v1.2.3 From 3ae5e62aedbd7e3c566e02579a76e759f7eb3cb9 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 1 Jan 2019 18:44:54 +0800 Subject: Target - Handle opaque types in size/align --- src/trans/target.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index dccc566d..9a855036 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -587,6 +587,8 @@ bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, } ), (Path, + if( te.binding.is_Opaque() ) + return false; const auto* repr = Target_GetTypeRepr(sp, resolve, ty); if( !repr ) { -- cgit v1.2.3 From 4eb0a6d7e4a600aeca52119fdf3a3bcf90cd6cbb Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Jan 2019 15:40:59 +0800 Subject: Trans - Packed types force outer alignment to 1 --- src/trans/target.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 9a855036..6a65be15 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -848,7 +848,7 @@ namespace { cur_ofs ++; } } - rv.align = max_align; + rv.align = packed ? 1 : max_align; rv.size = cur_ofs; rv.fields = ::std::move(fields); DEBUG("size = " << rv.size << ", align = " << rv.align); -- cgit v1.2.3 From 9e803f50b3bf0357665626fe59ea6160772b7da4 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 3 Mar 2019 19:33:29 +0800 Subject: Target - Return zero/infinite for extern type align/size --- src/trans/target.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 6a65be15..141f5b78 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -589,6 +589,13 @@ bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, (Path, if( te.binding.is_Opaque() ) return false; + if( te.binding.is_ExternType() ) + { + DEBUG("sizeof on extern type - unsized"); + out_align = 0; + out_size = SIZE_MAX; + return true; + } const auto* repr = Target_GetTypeRepr(sp, resolve, ty); if( !repr ) { @@ -1158,6 +1165,11 @@ namespace { { return make_type_repr_enum(sp, resolve, ty); } + else if( TU_TEST1(ty.m_data, Path, .binding.is_ExternType()) ) + { + // TODO: Do extern types need anything? + return nullptr; + } else if( ty.m_data.is_Primitive() ) { return nullptr; -- cgit v1.2.3 From 7c96c138d0ad2a3d223990e769441d6ec5074f1f Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 13 Jul 2019 18:52:31 +0800 Subject: Trans sizeof - Fix bug where sizeof<*const T> would return 2*ptr if T was ?Sized --- src/hir_typeck/static.cpp | 230 ++++++++++++++++++++++++++-------------------- src/hir_typeck/static.hpp | 10 ++ src/trans/codegen_c.cpp | 94 +++++-------------- src/trans/target.cpp | 29 ++++-- 4 files changed, 187 insertions(+), 176 deletions(-) (limited to 'src/trans/target.cpp') diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index ff085ac6..fd2e2a76 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -1647,107 +1647,13 @@ bool StaticTraitResolve::type_is_clone(const Span& sp, const ::HIR::TypeRef& ty) bool StaticTraitResolve::type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const { - TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e), - (Generic, - if( e.binding == 0xFFFF ) { - // TODO: Self: Sized? - return true; - } - else if( (e.binding >> 8) == 0 ) { - auto idx = e.binding & 0xFF; - assert( m_impl_generics ); - assert( idx < m_impl_generics->m_types.size() ); - return m_impl_generics->m_types[idx].m_is_sized; - } - else if( (e.binding >> 8) == 1 ) { - auto idx = e.binding & 0xFF; - assert( m_item_generics ); - assert( idx < m_item_generics->m_types.size() ); - return m_item_generics->m_types[idx].m_is_sized; - } - else { - BUG(sp, ""); - } - ), - (Path, - TU_MATCHA( (e.binding), (pbe), - (Unbound, - ), - (Opaque, - //auto pp = ::HIR::PathParams(); - //return this->find_impl(sp, m_lang_Sized, &pp, ty, [&](auto , bool){ return true; }, true); - // TODO: This can only be with UfcsKnown, so check if the trait specifies ?Sized - return true; - ), - (Struct, - // TODO: Destructure? - switch( pbe->m_struct_markings.dst_type ) - { - case ::HIR::StructMarkings::DstType::None: - return true; - case ::HIR::StructMarkings::DstType::Possible: - return type_is_sized( sp, e.path.m_data.as_Generic().m_params.m_types.at(pbe->m_struct_markings.unsized_param) ); - case ::HIR::StructMarkings::DstType::Slice: - case ::HIR::StructMarkings::DstType::TraitObject: - return false; - } - ), - (ExternType, - // Extern types aren't Sized - return false; - ), - (Enum, - ), - (Union, - ) - ) - return true; - ), - (Diverge, - // The ! type is kinda Sized ... - return true; - ), - (Closure, - return true; - ), - (Infer, - // Shouldn't be hit - return false; - ), - (Borrow, - return true; - ), - (Pointer, - return true; - ), - (Function, - return true; - ), - (Primitive, - // All primitives (except the unsized `str`) are Sized - return e != ::HIR::CoreType::Str; - ), - (Array, + switch( this->metadata_type(sp, ty) ) + { + case MetadataType::None: return true; - ), - (Slice, - return false; - ), - (TraitObject, + default: return false; - ), - (ErasedType, - // NOTE: All erased types are implicitly Sized - return true; - ), - (Tuple, - for(const auto& ty : e) - if( !type_is_sized(sp, ty) ) - return false; - return true; - ) - ) - throw ""; + } } bool StaticTraitResolve::type_is_impossible(const Span& sp, const ::HIR::TypeRef& ty) const { @@ -2018,7 +1924,133 @@ bool StaticTraitResolve::can_unsize(const Span& sp, const ::HIR::TypeRef& dst_ty DEBUG("Can't unsize, no rules matched"); return false; +} +MetadataType StaticTraitResolve::metadata_type(const Span& sp, const ::HIR::TypeRef& ty, bool err_on_unknown/*=false*/) const +{ + TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e), + (Generic, + if( e.binding == 0xFFFF ) { + // TODO: Self: Sized? + return MetadataType::None; + } + else if( (e.binding >> 8) == 0 ) { + auto idx = e.binding & 0xFF; + assert( m_impl_generics ); + assert( idx < m_impl_generics->m_types.size() ); + if( m_impl_generics->m_types[idx].m_is_sized ) { + return MetadataType::None; + } + else { + return MetadataType::Unknown; + } + } + else if( (e.binding >> 8) == 1 ) { + auto idx = e.binding & 0xFF; + assert( m_item_generics ); + assert( idx < m_item_generics->m_types.size() ); + if( m_item_generics->m_types[idx].m_is_sized ) { + return MetadataType::None; + } + else { + return MetadataType::Unknown; + } + } + else { + BUG(sp, "Unknown generic binding on " << ty); + } + ), + (Path, + TU_MATCHA( (e.binding), (pbe), + (Unbound, + // TODO: Should this return something else? + return MetadataType::Unknown; + ), + (Opaque, + //auto pp = ::HIR::PathParams(); + //return this->find_impl(sp, m_lang_Sized, &pp, ty, [&](auto , bool){ return true; }, true); + // TODO: This can only be with UfcsKnown, so check if the trait specifies ?Sized + //return MetadataType::Unknown; + return MetadataType::None; + ), + (Struct, + // TODO: Destructure? + switch( pbe->m_struct_markings.dst_type ) + { + case ::HIR::StructMarkings::DstType::None: + return MetadataType::None; + case ::HIR::StructMarkings::DstType::Possible: + return this->metadata_type( sp, e.path.m_data.as_Generic().m_params.m_types.at(pbe->m_struct_markings.unsized_param) ); + case ::HIR::StructMarkings::DstType::Slice: + return MetadataType::Slice; + case ::HIR::StructMarkings::DstType::TraitObject: + return MetadataType::TraitObject; + } + ), + (ExternType, + // Extern types aren't Sized, but have no metadata + return MetadataType::Zero; + ), + (Enum, + ), + (Union, + ) + ) + return MetadataType::None; + ), + (Diverge, + // The ! type is kinda Sized ... + return MetadataType::None; + ), + (Closure, + return MetadataType::None; + ), + (Infer, + // Shouldn't be hit + BUG(sp, "Found ivar? " << ty); + ), + (Borrow, + return MetadataType::None; + ), + (Pointer, + return MetadataType::None; + ), + (Function, + return MetadataType::None; + ), + (Primitive, + // All primitives (except the unsized `str`) are Sized + if( e == ::HIR::CoreType::Str ) + { + return MetadataType::Slice; + } + else + { + return MetadataType::None; + } + ), + (Array, + return MetadataType::None; + ), + (Slice, + return MetadataType::Slice; + ), + (TraitObject, + return MetadataType::TraitObject; + ), + (ErasedType, + // NOTE: All erased types are implicitly Sized + return MetadataType::None; + ), + (Tuple, + // TODO: Unsized tuples? are they a thing? + //for(const auto& ty : e) + // if( !type_is_sized(sp, ty) ) + // return false; + return MetadataType::None; + ) + ) + throw "bug"; } bool StaticTraitResolve::type_needs_drop_glue(const Span& sp, const ::HIR::TypeRef& ty) const diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp index 4ed72ce6..0d9449b1 100644 --- a/src/hir_typeck/static.hpp +++ b/src/hir_typeck/static.hpp @@ -11,6 +11,14 @@ #include "common.hpp" #include "impl_ref.hpp" +enum class MetadataType { + Unknown, // Unknown still + None, // Sized pointer + Zero, // No metadata, but still unsized + Slice, // usize metadata + TraitObject, // VTable pointer metadata +}; + class StaticTraitResolve { public: @@ -204,6 +212,8 @@ public: bool type_is_impossible(const Span& sp, const ::HIR::TypeRef& ty) const; bool can_unsize(const Span& sp, const ::HIR::TypeRef& dst, const ::HIR::TypeRef& src) const; + MetadataType metadata_type(const Span& sp, const ::HIR::TypeRef& ty, bool err_on_unknown=false) const; + /// Returns `true` if the passed type either implements Drop, or contains a type that implements Drop bool type_needs_drop_glue(const Span& sp, const ::HIR::TypeRef& ty) const; diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index e844a701..8b3b43ba 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -162,11 +162,6 @@ namespace { class CodeGenerator_C: public CodeGenerator { - enum class MetadataType { - None, - Slice, - TraitObject, - }; enum class Mode { //FullStd, Gcc, // Use GCC/Clang extensions @@ -916,6 +911,8 @@ namespace { case CodegenOutput::DynamicLibrary: args.push_back("/LD"); break; + default: + throw "bug"; } args.push_back(FMT("/Fe" << m_outfile_path)); @@ -4338,13 +4335,14 @@ namespace { } }; if( name == "size_of" ) { - // TODO: Target_GetSizeOf - emit_lvalue(e.ret_val); m_of << " = sizeof("; emit_ctype(params.m_types.at(0)); m_of << ")"; + size_t size = 0; + MIR_ASSERT(mir_res, Target_GetSizeOf(sp, m_resolve, params.m_types.at(0), size), "Can't get size of " << params.m_types.at(0)); + emit_lvalue(e.ret_val); m_of << " = " << size; } - else if( name == "min_align_of" ) { - // TODO: Target_GetAlignOf - //emit_lvalue(e.ret_val); m_of << " = alignof("; emit_ctype(params.m_types.at(0)); m_of << ")"; - emit_lvalue(e.ret_val); m_of << " = ALIGNOF("; emit_ctype(params.m_types.at(0)); m_of << ")"; + else if( name == "min_align_of" || name == "align_of" ) { + size_t align = 0; + MIR_ASSERT(mir_res, Target_GetAlignOf(sp, m_resolve, params.m_types.at(0), align), "Can't get alignment of " << params.m_types.at(0)); + emit_lvalue(e.ret_val); m_of << " = " << align; } else if( name == "size_of_val" ) { emit_lvalue(e.ret_val); m_of << " = "; @@ -4473,7 +4471,9 @@ namespace { emit_lvalue(e.ret_val); m_of << ".META = "; switch(dst_meta) { + case MetadataType::Unknown: assert(!"Impossible"); case MetadataType::None: assert(!"Impossible"); + case MetadataType::Zero: assert(!"Impossible"); case MetadataType::Slice: m_of << "(size_t)"; break; case MetadataType::TraitObject: m_of << "(const void*)"; break; } @@ -5286,8 +5286,10 @@ namespace { const char* make_fcn = nullptr; switch( metadata_type(ty) ) { + case MetadataType::Unknown: + MIR_BUG(*m_mir_res, ty << " unknown metadata"); case MetadataType::None: - + case MetadataType::Zero: if( this->type_is_bad_zst(ty) && (slot.is_Field() || slot.is_Downcast()) ) { m_of << indent << Trans_Mangle(p) << "((void*)&"; @@ -5575,7 +5577,10 @@ namespace { const auto& ity = *ty.m_data.as_Borrow().inner; switch( metadata_type(ity) ) { + case MetadataType::Unknown: + MIR_BUG(*m_mir_res, ity << " - Unknown meta"); case MetadataType::None: + case MetadataType::Zero: emit_dst(); m_of << " = &" << Trans_Mangle(e); break; case MetadataType::Slice: @@ -6071,61 +6076,9 @@ namespace { return ::HIR::TypeRef(); } } - // TODO: Move this to a more common location - MetadataType metadata_type(const ::HIR::TypeRef& ty) const - { - if( ty == ::HIR::CoreType::Str || ty.m_data.is_Slice() ) { - return MetadataType::Slice; - } - else if( ty.m_data.is_TraitObject() ) { - return MetadataType::TraitObject; - } - else if( ty.m_data.is_Path() ) - { - TU_MATCH_DEF( ::HIR::TypeRef::TypePathBinding, (ty.m_data.as_Path().binding), (tpb), - ( - MIR_BUG(*m_mir_res, "Unbound/opaque path in trans - " << ty); - ), - (Struct, - switch( tpb->m_struct_markings.dst_type ) - { - case ::HIR::StructMarkings::DstType::None: - return MetadataType::None; - case ::HIR::StructMarkings::DstType::Possible: { - // TODO: How to figure out? Lazy way is to check the monomorpised type of the last field (structs only) - const auto& path = ty.m_data.as_Path().path.m_data.as_Generic(); - const auto& str = *ty.m_data.as_Path().binding.as_Struct(); - auto monomorph = [&](const auto& tpl) { - auto rv = monomorphise_type(sp, str.m_params, path.m_params, tpl); - m_resolve.expand_associated_types(sp, rv); - return rv; - }; - TU_MATCHA( (str.m_data), (se), - (Unit, MIR_BUG(*m_mir_res, "Unit-like struct with DstType::Possible"); ), - (Tuple, return metadata_type( monomorph(se.back().ent) ); ), - (Named, return metadata_type( monomorph(se.back().second.ent) ); ) - ) - //MIR_TODO(*m_mir_res, "Determine DST type when ::Possible - " << ty); - return MetadataType::None; - } - case ::HIR::StructMarkings::DstType::Slice: - return MetadataType::Slice; - case ::HIR::StructMarkings::DstType::TraitObject: - return MetadataType::TraitObject; - } - ), - (Union, - return MetadataType::None; - ), - (Enum, - return MetadataType::None; - ) - ) - throw ""; - } - else { - return MetadataType::None; - } + + MetadataType metadata_type(const ::HIR::TypeRef& ty) const { + return m_resolve.metadata_type(m_mir_res ? m_mir_res->sp : sp, ty); } void emit_ctype_ptr(const ::HIR::TypeRef& inner_ty, ::FmtLambda inner) { @@ -6134,9 +6087,12 @@ namespace { //} //else { - switch( metadata_type(inner_ty) ) + switch( this->metadata_type(inner_ty) ) { + case MetadataType::Unknown: + BUG(sp, inner_ty << " unknown metadata type"); case MetadataType::None: + case MetadataType::Zero: emit_ctype(inner_ty, FMT_CB(ss, ss << "*" << inner;)); break; case MetadataType::Slice: @@ -6151,7 +6107,7 @@ namespace { bool is_dst(const ::HIR::TypeRef& ty) const { - return metadata_type(ty) != MetadataType::None; + return this->metadata_type(ty) != MetadataType::None; } }; Span CodeGenerator_C::sp; diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 141f5b78..126f71fb 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -659,26 +659,39 @@ bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, // - Alignment is machine native out_align = g_target.m_arch.m_pointer_bits / 8; // - Size depends on Sized-nes of the parameter - if( resolve.type_is_sized(sp, *te.inner) ) + // TODO: Handle different types of Unsized (ones with different pointer sizes) + switch(resolve.metadata_type(sp, *te.inner)) { + case MetadataType::Unknown: + return false; + case MetadataType::None: + case MetadataType::Zero: out_size = g_target.m_arch.m_pointer_bits / 8; - return true; + break; + case MetadataType::Slice: + case MetadataType::TraitObject: + out_size = g_target.m_arch.m_pointer_bits / 8 * 2; + break; } - // TODO: Handle different types of Unsized (ones with different pointer sizes) - out_size = g_target.m_arch.m_pointer_bits / 8 * 2; return true; ), (Pointer, // - Alignment is machine native out_align = g_target.m_arch.m_pointer_bits / 8; // - Size depends on Sized-nes of the parameter - if( resolve.type_is_sized(sp, *te.inner) ) + switch(resolve.metadata_type(sp, *te.inner)) { + case MetadataType::Unknown: + return false; + case MetadataType::None: + case MetadataType::Zero: out_size = g_target.m_arch.m_pointer_bits / 8; - return true; + break; + case MetadataType::Slice: + case MetadataType::TraitObject: + out_size = g_target.m_arch.m_pointer_bits / 8 * 2; + break; } - // TODO: Handle different types of Unsized (ones with different pointer sizes) - out_size = g_target.m_arch.m_pointer_bits / 8 * 2; return true; ), (Function, -- cgit v1.2.3 From d0e905bc00ea805a73fa116c68e25a2a66d221ad Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 26 Oct 2019 10:53:02 +0800 Subject: Trans Target - Avoid reading an undefined value --- src/trans/target.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 126f71fb..5f52912e 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -718,7 +718,7 @@ bool Target_GetAlignOf(const Span& sp, const StaticTraitResolve& resolve, const { size_t ignore_size; bool rv = Target_GetSizeAndAlignOf(sp, resolve, ty, ignore_size, out_align); - if( ignore_size == SIZE_MAX ) + if( rv && ignore_size == SIZE_MAX ) BUG(sp, "Getting alignment of Unsized type - " << ty); return rv; } -- cgit v1.2.3 From a1a03108029fa6bd092bc8f141acbc4cdb210e01 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 29 Oct 2019 20:37:51 +0800 Subject: minicargo - Fixes to build script support for winapi --- src/trans/target.cpp | 8 ++++---- tools/common/target_detect.h | 8 ++++---- tools/minicargo/build.cpp | 15 ++++++++------- tools/minicargo/stringlist.h | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 9172481a..de5492a8 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -404,21 +404,21 @@ namespace ARCH_M68K }; } - else if(target_name == "i586-windows-gnu") + else if(target_name == "i586-pc-windows-gnu") { return TargetSpec { "windows", "windows", "gnu", {CodegenMode::Gnu11, true, "mingw32", BACKEND_C_OPTS_GNU}, ARCH_X86 }; } - else if(target_name == "x86_64-windows-gnu") + else if(target_name == "x86_64-pc-windows-gnu") { return TargetSpec { "windows", "windows", "gnu", {CodegenMode::Gnu11, false, "x86_64-w64-mingw32", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } - else if (target_name == "x86-windows-msvc") + else if (target_name == "x86-pc-windows-msvc") { // TODO: Should this include the "kernel32.lib" inclusion? return TargetSpec { @@ -426,7 +426,7 @@ namespace ARCH_X86 }; } - else if (target_name == "x86_64-windows-msvc") + else if (target_name == "x86_64-pc-windows-msvc") { return TargetSpec { "windows", "windows", "msvc", {CodegenMode::Msvc, true, "amd64", {}, {}}, diff --git a/tools/common/target_detect.h b/tools/common/target_detect.h index 1bfc7dd9..dda4bc31 100644 --- a/tools/common/target_detect.h +++ b/tools/common/target_detect.h @@ -10,9 +10,9 @@ // - Windows (MSVC) #ifdef _MSC_VER # if defined(_WIN64) -# define DEFAULT_TARGET_NAME "x86_64-windows-msvc" +# define DEFAULT_TARGET_NAME "x86_64-pc-windows-msvc" # else -# define DEFAULT_TARGET_NAME "x86-windows-msvc" +# define DEFAULT_TARGET_NAME "x86-pc-windows-msvc" # endif // - Linux #elif defined(__linux__) @@ -32,9 +32,9 @@ // - MinGW #elif defined(__MINGW32__) # if defined(_WIN64) -# define DEFAULT_TARGET_NAME "x86_64-windows-gnu" +# define DEFAULT_TARGET_NAME "x86_64-pc-windows-gnu" # else -# define DEFAULT_TARGET_NAME "i586-windows-gnu" +# define DEFAULT_TARGET_NAME "i586-pc-windows-gnu" # endif // - FreeBSD #elif defined(__FreeBSD__) diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 5eb07104..efacb6f8 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -1082,13 +1082,13 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget& StringListKV env; env.push_back("CARGO_MANIFEST_DIR", manifest.directory().to_absolute()); //env.push_back("CARGO_MANIFEST_LINKS", manifest.m_links); - //for(const auto& feat : manifest.m_active_features) - //{ - // ::std::string fn = "CARGO_FEATURE_"; - // for(char c : feat) - // fn += c == '-' ? '_' : tolower(c); - // env.push_back(fn, manifest.m_links); - //} + for(const auto& feat : manifest.active_features()) + { + ::std::string fn = "CARGO_FEATURE_"; + for(char c : feat) + fn += c == '-' ? '_' : toupper(c); + env.push_back(fn, "1"); + } //env.push_back("CARGO_CFG_RELEASE", ""); env.push_back("OUT_DIR", out_dir); env.push_back("TARGET", m_opts.target_name ? m_opts.target_name : HOST_TARGET); @@ -1206,6 +1206,7 @@ bool Builder::spawn_process(const char* exe_name, const StringList& args, const #else for(auto kv : env) { + DEBUG("putenv " << kv.first << "=" << kv.second); _putenv_s(kv.first, kv.second); } #endif diff --git a/tools/minicargo/stringlist.h b/tools/minicargo/stringlist.h index 4381121b..08b74c4b 100644 --- a/tools/minicargo/stringlist.h +++ b/tools/minicargo/stringlist.h @@ -78,7 +78,7 @@ public: }; class StringListKV: private StringList { - ::std::vector m_keys; + StringList m_keys; public: StringListKV() { @@ -99,6 +99,16 @@ public: m_keys.push_back(k); StringList::push_back(v); } + void push_back(::std::string k, ::std::string v) + { + m_keys.push_back(k); + StringList::push_back(v); + } + void push_back(::std::string k, const char* v) + { + m_keys.push_back(k); + StringList::push_back(v); + } struct Iter { const StringListKV& v; @@ -108,7 +118,7 @@ public: this->i++; } ::std::pair operator*() { - return ::std::make_pair(this->v.m_keys[this->i], this->v.get_vec()[this->i]); + return ::std::make_pair(this->v.m_keys.get_vec()[this->i], this->v.get_vec()[this->i]); } bool operator!=(const Iter& x) const { return this->i != x.i; @@ -118,7 +128,7 @@ public: return Iter { *this, 0 }; } Iter end() const { - return Iter { *this, m_keys.size() }; + return Iter { *this, m_keys.get_vec().size() }; } friend ::std::ostream& operator<<(::std::ostream& os, const StringListKV& x) { -- cgit v1.2.3