summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-08-14 19:18:24 -0400
committerGitHub <noreply@github.com>2018-08-14 19:18:24 -0400
commit40d24bb085a1a0bd11f7cf4dd87c52de529302ca (patch)
tree79a015d785f110b572fad85cd7aed70e3f50b260
parentbb6a1205a0e81271bf90aec33d33e2e3ca0ae7d1 (diff)
parent6e7d9bebd8c95a8ca7088cf02c17aea811d20783 (diff)
Auto merge of #1366 - gnzlbg:vec, r=emiliov0.38.0
Map vector types to arrays and pass them by value This PR maps vector types to arrays and passes them by value (that is, they are passed to C as `[T; N]`. This already allows defining them as a blacklisted opaque type, such that the user can provide its own definition from e.g. `std::arch`. A subsequent PR should map vector types to unit structs with a private member: ```rust #[repr(align(16))] pub struct __m128([f32; 4]); ``` to make their alignment at least be correct. This should allow transmuting `std::arch` types to these types properly. Once that is done, we probably want to detect the canonical vector types (e.g. `__m128`) and pull in the type from `std`/`core`::arch instead.
-rw-r--r--src/codegen/impl_debug.rs9
-rw-r--r--src/codegen/impl_partialeq.rs7
-rw-r--r--src/codegen/mod.rs3
-rw-r--r--src/ir/analysis/derive_copy.rs1
-rw-r--r--src/ir/analysis/derive_debug.rs1
-rw-r--r--src/ir/analysis/derive_default.rs1
-rw-r--r--src/ir/analysis/derive_hash.rs12
-rw-r--r--src/ir/analysis/derive_partialeq_or_partialord.rs9
-rw-r--r--src/ir/analysis/has_float.rs8
-rw-r--r--src/ir/analysis/has_type_param_in_array.rs1
-rw-r--r--src/ir/analysis/sizedness.rs4
-rw-r--r--src/ir/ty.rs22
-rw-r--r--tests/expectations/tests/vector.rs16
-rw-r--r--tests/headers/vector.hpp6
14 files changed, 89 insertions, 11 deletions
diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs
index ab934ed6..0842d849 100644
--- a/src/codegen/impl_debug.rs
+++ b/src/codegen/impl_debug.rs
@@ -197,6 +197,15 @@ impl<'a> ImplDebug<'a> for Item {
))
}
}
+ TypeKind::Vector(_, len) => {
+ let self_ids = 0..len;
+ Some((
+ format!("{}({{}})", name),
+ vec![quote! {
+ #(format!("{:?}", self.#self_ids)),*
+ }]
+ ))
+ }
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs
index a05c65e7..66565db6 100644
--- a/src/codegen/impl_partialeq.rs
+++ b/src/codegen/impl_partialeq.rs
@@ -115,6 +115,13 @@ fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens
&self. #name_ident [..] == &other. #name_ident [..]
}
},
+ TypeKind::Vector(_, len) => {
+ let self_ids = 0..len;
+ let other_ids = 0..len;
+ quote! {
+ #(self.#self_ids == other.#other_ids &&)* true
+ }
+ },
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index cdf0134a..f596ddda 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -595,6 +595,7 @@ impl CodeGenerator for Type {
TypeKind::Float(..) |
TypeKind::Complex(..) |
TypeKind::Array(..) |
+ TypeKind::Vector(..) |
TypeKind::Pointer(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
@@ -3050,7 +3051,7 @@ impl TryToRustTy for Type {
::#prefix::option::Option<#ty>
})
}
- TypeKind::Array(item, len) => {
+ TypeKind::Array(item, len) | TypeKind::Vector(item, len) => {
let ty = item.try_to_rust_ty(ctx, &())?;
Ok(quote! {
[ #ty ; #len ]
diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs
index 1e8dc819..abb25174 100644
--- a/src/ir/analysis/derive_copy.rs
+++ b/src/ir/analysis/derive_copy.rs
@@ -167,6 +167,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
TypeKind::NullPtr |
TypeKind::Int(..) |
TypeKind::Float(..) |
+ TypeKind::Vector(..) |
TypeKind::Complex(..) |
TypeKind::Function(..) |
TypeKind::Enum(..) |
diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs
index b191d37d..b0d70f15 100644
--- a/src/ir/analysis/derive_debug.rs
+++ b/src/ir/analysis/derive_debug.rs
@@ -182,6 +182,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
+ TypeKind::Vector(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs
index e319166d..a43d7737 100644
--- a/src/ir/analysis/derive_default.rs
+++ b/src/ir/analysis/derive_default.rs
@@ -204,6 +204,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
TypeKind::Function(..) |
TypeKind::Int(..) |
TypeKind::Float(..) |
+ TypeKind::Vector(..) |
TypeKind::Complex(..) => {
trace!(" simple type that can always derive Default");
ConstrainResult::Same
diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs
index c23a891e..fe56ed7c 100644
--- a/src/ir/analysis/derive_hash.rs
+++ b/src/ir/analysis/derive_hash.rs
@@ -202,6 +202,18 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
self.insert(id)
}
}
+ TypeKind::Vector(t, len) => {
+ if self.cannot_derive_hash.contains(&t.into()) {
+ trace!(
+ " vectors of T for which we cannot derive Hash \
+ also cannot derive Hash"
+ );
+ return self.insert(id);
+ }
+ assert_ne!(len, 0, "vectors cannot have zero length");
+ trace!(" vector can derive Hash");
+ ConstrainResult::Same
+ }
TypeKind::Pointer(inner) => {
let inner_type =
diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs
index cebdceef..23d55c13 100644
--- a/src/ir/analysis/derive_partialeq_or_partialord.rs
+++ b/src/ir/analysis/derive_partialeq_or_partialord.rs
@@ -148,7 +148,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
}
match *ty.kind() {
- // Handle the simple cases. These can derive partialeq without further
+ // Handle the simple cases. These can derive partialeq/partialord without further
// information.
TypeKind::Void |
TypeKind::NullPtr |
@@ -199,6 +199,13 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
return CanDerive::ArrayTooLarge;
}
}
+ TypeKind::Vector(..) => {
+ // FIXME: vectors always can derive PartialEq, but they should
+ // not derive PartialOrd:
+ // https://github.com/rust-lang-nursery/packed_simd/issues/48
+ trace!(" vectors cannot derive `PartialEq`/`PartialOrd`");
+ return CanDerive::No;
+ }
TypeKind::Pointer(inner) => {
let inner_type =
diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs
index 193862c0..53e6a491 100644
--- a/src/ir/analysis/has_float.rs
+++ b/src/ir/analysis/has_float.rs
@@ -148,6 +148,14 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
trace!(" Array with type T that do not have float also do not have float");
ConstrainResult::Same
}
+ TypeKind::Vector(t, _) => {
+ if self.has_float.contains(&t.into()) {
+ trace!(" Vector with type T that has float also has float");
+ return self.insert(id)
+ }
+ trace!(" Vector with type T that do not have float also do not have float");
+ ConstrainResult::Same
+ }
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs
index aa8d34be..b7afe043 100644
--- a/src/ir/analysis/has_type_param_in_array.rs
+++ b/src/ir/analysis/has_type_param_in_array.rs
@@ -130,6 +130,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::NullPtr |
TypeKind::Int(..) |
TypeKind::Float(..) |
+ TypeKind::Vector(..) |
TypeKind::Complex(..) |
TypeKind::Function(..) |
TypeKind::Enum(..) |
diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs
index e82c1798..e49b2570 100644
--- a/src/ir/analysis/sizedness.rs
+++ b/src/ir/analysis/sizedness.rs
@@ -295,6 +295,10 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> {
trace!(" arrays of > 0 elements are not zero-sized");
self.insert(id, SizednessResult::NonZeroSized)
}
+ TypeKind::Vector(..) => {
+ trace!(" vectors are not zero-sized");
+ self.insert(id, SizednessResult::NonZeroSized)
+ }
TypeKind::Comp(ref info) => {
trace!(" comp considers its own fields and bases");
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index b805dd62..9cc097d4 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -320,6 +320,7 @@ impl Type {
match self.kind {
TypeKind::TypeParam |
TypeKind::Array(..) |
+ TypeKind::Vector(..) |
TypeKind::Comp(..) |
TypeKind::Opaque |
TypeKind::Int(..) |
@@ -472,6 +473,7 @@ impl TypeKind {
TypeKind::Alias(..) => "Alias",
TypeKind::TemplateAlias(..) => "TemplateAlias",
TypeKind::Array(..) => "Array",
+ TypeKind::Vector(..) => "Vector",
TypeKind::Function(..) => "Function",
TypeKind::Enum(..) => "Enum",
TypeKind::Pointer(..) => "Pointer",
@@ -565,6 +567,7 @@ impl TemplateParameters for TypeKind {
TypeKind::Float(_) |
TypeKind::Complex(_) |
TypeKind::Array(..) |
+ TypeKind::Vector(..) |
TypeKind::Function(_) |
TypeKind::Enum(_) |
TypeKind::Pointer(_) |
@@ -627,6 +630,9 @@ pub enum TypeKind {
/// template parameters.
TemplateAlias(TypeId, Vec<TypeId>),
+ /// A packed vector type: element type, number of elements
+ Vector(TypeId, usize),
+
/// An array of a type and a length.
Array(TypeId, usize),
@@ -1148,12 +1154,15 @@ impl Type {
TypeKind::Comp(complex)
}
- // FIXME: We stub vectors as arrays since in 99% of the cases the
- // layout is going to be correct, and there's no way we can generate
- // vector types properly in Rust for now.
- //
- // That being said, that should be fixed eventually.
- CXType_Vector |
+ CXType_Vector => {
+ let inner = Item::from_ty(
+ ty.elem_type().as_ref().unwrap(),
+ location,
+ None,
+ ctx,
+ ).expect("Not able to resolve vector element?");
+ TypeKind::Vector(inner, ty.num_elements().unwrap())
+ }
CXType_ConstantArray => {
let inner = Item::from_ty(
ty.elem_type().as_ref().unwrap(),
@@ -1214,6 +1223,7 @@ impl Trace for Type {
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) |
TypeKind::Array(inner, _) |
+ TypeKind::Vector(inner, _) |
TypeKind::Alias(inner) |
TypeKind::ResolvedTypeRef(inner) => {
tracer.visit_kind(inner.into(), EdgeKind::TypeReference);
diff --git a/tests/expectations/tests/vector.rs b/tests/expectations/tests/vector.rs
index 357b9ef4..86a9d737 100644
--- a/tests/expectations/tests/vector.rs
+++ b/tests/expectations/tests/vector.rs
@@ -1,8 +1,11 @@
/* automatically generated by rust-bindgen */
-
-#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
@@ -32,3 +35,10 @@ fn bindgen_test_layout_foo() {
)
);
}
+pub type __m128 = [f32; 4usize];
+pub type __m128d = [f64; 2usize];
+pub type __m128i = [::std::os::raw::c_longlong; 2usize];
+extern "C" {
+ #[link_name = "\u{1}_Z3fooDv2_xDv2_d"]
+ pub fn foo(arg1: __m128i, arg2: __m128d) -> __m128;
+}
diff --git a/tests/headers/vector.hpp b/tests/headers/vector.hpp
index 4707f77f..173aa022 100644
--- a/tests/headers/vector.hpp
+++ b/tests/headers/vector.hpp
@@ -1,3 +1,9 @@
struct foo {
__attribute__((__vector_size__(1 * sizeof(long long)))) long long mMember;
};
+
+typedef float __m128 __attribute__ ((__vector_size__ (16)));
+typedef double __m128d __attribute__((__vector_size__(16)));
+typedef long long __m128i __attribute__((__vector_size__(16)));
+
+__m128 foo(__m128i, __m128d);