summaryrefslogtreecommitdiff
path: root/src/codegen/helpers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/helpers.rs')
-rw-r--r--src/codegen/helpers.rs53
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] }
+ }
+ }
}
}