summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/helpers.rs43
-rw-r--r--src/codegen/mod.rs4
-rw-r--r--tests/expectations/tests/convert-floats.rs11
-rw-r--r--tests/expectations/tests/long_double.rs32
-rw-r--r--tests/expectations/tests/union_bitfield_1_0.rs12
5 files changed, 85 insertions, 17 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs
index 55430fe9..343f1e30 100644
--- a/src/codegen/helpers.rs
+++ b/src/codegen/helpers.rs
@@ -122,6 +122,7 @@ pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
pub mod ast_ty {
use ir::context::BindgenContext;
use ir::function::FunctionSig;
+ use ir::layout::Layout;
use ir::ty::FloatKind;
use quote;
use proc_macro2;
@@ -144,22 +145,44 @@ pub mod ast_ty {
pub fn float_kind_rust_type(
ctx: &BindgenContext,
fk: FloatKind,
+ layout: Option<Layout>,
) -> quote::Tokens {
- // TODO: we probably should just take the type layout into
- // account?
+ // TODO: we probably should take the type layout into account more
+ // often?
//
// Also, maybe this one shouldn't be the default?
- //
- // FIXME: `c_longdouble` doesn't seem to be defined in some
- // systems, so we use `c_double` directly.
match (fk, ctx.options().convert_floats) {
(FloatKind::Float, true) => quote! { f32 },
- (FloatKind::Double, true) |
- (FloatKind::LongDouble, true) => quote! { f64 },
+ (FloatKind::Double, true) => quote! { f64 },
(FloatKind::Float, false) => raw_type(ctx, "c_float"),
- (FloatKind::Double, false) |
- (FloatKind::LongDouble, false) => raw_type(ctx, "c_double"),
- (FloatKind::Float128, _) => quote! { [u8; 16] },
+ (FloatKind::Double, false) => raw_type(ctx, "c_double"),
+ (FloatKind::LongDouble, _) => {
+ match layout {
+ Some(layout) => {
+ match layout.size {
+ 4 => quote! { f32 },
+ 8 => quote! { f64 },
+ // TODO(emilio): If rust ever gains f128 we should
+ // use it here and below.
+ _ => super::integer_type(ctx, layout).unwrap_or(quote! { f64 }),
+ }
+ }
+ None => {
+ debug_assert!(
+ false,
+ "How didn't we know the layout for a primitive type?"
+ );
+ quote! { f64 }
+ }
+ }
+ }
+ (FloatKind::Float128, _) => {
+ if ctx.options().rust_features.i128_and_u128 {
+ quote! { u128 }
+ } else {
+ quote! { [u64; 2] }
+ }
+ }
}
}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index b5188916..67d6b6d5 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -3077,9 +3077,9 @@ impl TryToRustTy for Type {
}
}
}
- TypeKind::Float(fk) => Ok(float_kind_rust_type(ctx, fk)),
+ TypeKind::Float(fk) => Ok(float_kind_rust_type(ctx, fk, self.layout(ctx))),
TypeKind::Complex(fk) => {
- let float_path = float_kind_rust_type(ctx, fk);
+ let float_path = float_kind_rust_type(ctx, fk, self.layout(ctx));
ctx.generated_bindgen_complex();
Ok(if ctx.options().enable_cxx_namespaces {
diff --git a/tests/expectations/tests/convert-floats.rs b/tests/expectations/tests/convert-floats.rs
index e1e93a13..e6abee16 100644
--- a/tests/expectations/tests/convert-floats.rs
+++ b/tests/expectations/tests/convert-floats.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
+)]
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
#[repr(C)]
@@ -16,7 +19,7 @@ pub struct foo {
pub bar: ::std::os::raw::c_float,
pub baz: ::std::os::raw::c_float,
pub bazz: ::std::os::raw::c_double,
- pub bazzz: *mut ::std::os::raw::c_double,
+ pub bazzz: *mut f64,
pub complexFloat: __BindgenComplex<::std::os::raw::c_float>,
pub complexDouble: __BindgenComplex<::std::os::raw::c_double>,
}
diff --git a/tests/expectations/tests/long_double.rs b/tests/expectations/tests/long_double.rs
new file mode 100644
index 00000000..05d56414
--- /dev/null
+++ b/tests/expectations/tests/long_double.rs
@@ -0,0 +1,32 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct foo {
+ pub bar: u128,
+}
+#[test]
+fn bindgen_test_layout_foo() {
+ assert_eq!(
+ ::std::mem::size_of::<foo>(),
+ 16usize,
+ concat!("Size of: ", stringify!(foo))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<foo>(),
+ 16usize,
+ concat!("Alignment of ", stringify!(foo))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<foo>())).bar as *const _ as usize },
+ 0usize,
+ concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar))
+ );
+}
diff --git a/tests/expectations/tests/union_bitfield_1_0.rs b/tests/expectations/tests/union_bitfield_1_0.rs
index b33d9873..adab161e 100644
--- a/tests/expectations/tests/union_bitfield_1_0.rs
+++ b/tests/expectations/tests/union_bitfield_1_0.rs
@@ -1,6 +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(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -279,3 +284,8 @@ impl Default for HasBigBitfield {
unsafe { ::std::mem::zeroed() }
}
}
+impl ::std::cmp::PartialEq for HasBigBitfield {
+ fn eq(&self, other: &HasBigBitfield) -> bool {
+ &self.bindgen_union_field[..] == &other.bindgen_union_field[..]
+ }
+}