diff options
Diffstat (limited to 'src/codegen/helpers.rs')
-rw-r--r-- | src/codegen/helpers.rs | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index b7c3df7f..343f1e30 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -59,14 +59,14 @@ pub mod attributes { /// Generates a proper type for a field or type with a given `Layout`, that is, /// a type with the correct size and alignment restrictions. -pub fn blob(layout: Layout) -> quote::Tokens { +pub fn blob(ctx: &BindgenContext, layout: Layout) -> quote::Tokens { let opaque = layout.opaque(); // FIXME(emilio, #412): We fall back to byte alignment, but there are // some things that legitimately are more than 8-byte aligned. // // Eventually we should be able to `unwrap` here, but... - let ty_name = match opaque.known_rust_type_for_array() { + let ty_name = match opaque.known_rust_type_for_array(ctx) { Some(ty) => ty, None => { warn!("Found unknown alignment on code generation!"); @@ -76,7 +76,7 @@ pub fn blob(layout: Layout) -> quote::Tokens { let ty_name = Term::new(ty_name, Span::call_site()); - let data_len = opaque.array_size().unwrap_or(layout.size); + let data_len = opaque.array_size(ctx).unwrap_or(layout.size); if data_len == 1 { quote! { @@ -90,8 +90,8 @@ pub fn blob(layout: Layout) -> quote::Tokens { } /// Integer type of the same size as the given `Layout`. -pub fn integer_type(layout: Layout) -> Option<quote::Tokens> { - let name = Layout::known_type_for_size(layout.size)?; +pub fn integer_type(ctx: &BindgenContext, layout: Layout) -> Option<quote::Tokens> { + let name = Layout::known_type_for_size(ctx, layout.size)?; let name = Term::new(name, Span::call_site()); Some(quote! { #name }) } @@ -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] } + } + } } } |