diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-09-19 03:04:47 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-09-19 03:05:12 +0200 |
commit | 7455e3b5b98c392bd4c313b851cda2857581ed8f (patch) | |
tree | 8eb313679d1c0fb66c5abaceb43a137e8ae03c6c | |
parent | 9087c2f065c8ae868ad418afee0c4bc5921337e6 (diff) |
Teach the blob code to generate i128 / u128 if available.
This is very mechanical and boring, but needed.
-rw-r--r-- | src/codegen/helpers.rs | 10 | ||||
-rw-r--r-- | src/codegen/impl_debug.rs | 2 | ||||
-rw-r--r-- | src/codegen/mod.rs | 20 | ||||
-rw-r--r-- | src/codegen/struct_layout.rs | 2 | ||||
-rw-r--r-- | src/ir/analysis/derive_copy.rs | 2 | ||||
-rw-r--r-- | src/ir/analysis/derive_debug.rs | 6 | ||||
-rw-r--r-- | src/ir/analysis/derive_default.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/derive_hash.rs | 8 | ||||
-rw-r--r-- | src/ir/analysis/derive_partialeq_or_partialord.rs | 8 | ||||
-rw-r--r-- | src/ir/context.rs | 2 | ||||
-rw-r--r-- | src/ir/derive.rs | 20 | ||||
-rw-r--r-- | src/ir/function.rs | 17 | ||||
-rw-r--r-- | src/ir/item.rs | 2 | ||||
-rw-r--r-- | src/ir/layout.rs | 50 |
14 files changed, 77 insertions, 76 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index b7c3df7f..55430fe9 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 }) } diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index 0f8e4d96..2c6d36d9 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -236,7 +236,7 @@ impl<'a> ImplDebug<'a> for Item { let inner_type = ctx.resolve_type(inner).canonical_type(ctx); match *inner_type.kind() { TypeKind::Function(ref sig) - if !sig.can_trivially_derive_debug() => { + if !sig.can_trivially_derive_debug(ctx) => { Some((format!("{}: FunctionPointer", name), vec![])) } _ => debug_print(name, quote! { #name_ident }), diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 86a29c50..b5188916 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1185,7 +1185,7 @@ impl Bitfield { let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( "Bitfield without layout? Gah!", ); - let bitfield_int_ty = helpers::blob(bitfield_ty_layout); + let bitfield_int_ty = helpers::blob(ctx, bitfield_ty_layout); let offset = self.offset_into_unit(); let width = self.width() as u8; @@ -1367,7 +1367,7 @@ impl<'a> FieldCodegen<'a> for Bitfield { let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( "Bitfield without layout? Gah!", ); - let bitfield_int_ty = match helpers::integer_type(bitfield_ty_layout) { + let bitfield_int_ty = match helpers::integer_type(ctx, bitfield_ty_layout) { Some(int_ty) => { *bitfield_representable_as_int = true; int_ty @@ -1547,7 +1547,7 @@ impl CodeGenerator for CompInfo { } let layout = layout.expect("Unable to get layout information?"); - let ty = helpers::blob(layout); + let ty = helpers::blob(ctx, layout); fields.push(if self.can_be_rust_union(ctx) { quote! { @@ -1572,7 +1572,7 @@ impl CodeGenerator for CompInfo { Some(l) => { explicit_align = Some(l.align); - let ty = helpers::blob(l); + let ty = helpers::blob(ctx, l); fields.push(quote! { pub _bindgen_opaque_blob: #ty , }); @@ -1595,7 +1595,7 @@ impl CodeGenerator for CompInfo { } else { explicit_align = Some(layout.align); if !ctx.options().rust_features.repr_align { - let ty = helpers::blob(Layout::new(0, layout.align)); + let ty = helpers::blob(ctx, Layout::new(0, layout.align)); fields.push(quote! { pub __bindgen_align: #ty , }); @@ -1629,7 +1629,7 @@ impl CodeGenerator for CompInfo { }; if has_address { - let ty = helpers::blob(Layout::new(1, 1)); + let ty = helpers::blob(ctx, Layout::new(1, 1)); fields.push(quote! { pub _address: #ty, }); @@ -2800,7 +2800,7 @@ trait TryToOpaque { extra: &Self::Extra, ) -> error::Result<quote::Tokens> { self.try_get_layout(ctx, extra).map(|layout| { - helpers::blob(layout) + helpers::blob(ctx, layout) }) } } @@ -2827,7 +2827,7 @@ trait ToOpaque: TryToOpaque { extra: &Self::Extra, ) -> quote::Tokens { let layout = self.get_layout(ctx, extra); - helpers::blob(layout) + helpers::blob(ctx, layout) } } @@ -2885,7 +2885,7 @@ where |_| if let Ok(layout) = self.try_get_layout(ctx, extra) { - Ok(helpers::blob(layout)) + Ok(helpers::blob(ctx, layout)) } else { Err(error::Error::NoLayoutForOpaqueBlob) }, @@ -3037,7 +3037,7 @@ impl TryToRustTy for Type { IntKind::LongLong => Ok(raw_type(ctx, "c_longlong")), IntKind::ULongLong => Ok(raw_type(ctx, "c_ulonglong")), IntKind::WChar { size } => { - let ty = Layout::known_type_for_size(size) + let ty = Layout::known_type_for_size(ctx, size) .expect("Non-representable wchar_t?"); let ident = ctx.rust_ident_raw(ty); Ok(quote! { #ident }) diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 6de7e030..b70fb658 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -306,7 +306,7 @@ impl<'a> StructLayoutTracker<'a> { } fn padding_field(&mut self, layout: Layout) -> quote::Tokens { - let ty = helpers::blob(layout); + let ty = helpers::blob(self.ctx, layout); let padding_count = self.padding_count; self.padding_count += 1; diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index fbe6e882..9d0bcd19 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -149,7 +149,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { if item.is_opaque(self.ctx, &()) { let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_copy() + l.opaque().can_trivially_derive_copy(self.ctx) }); return if layout_can_derive { trace!(" we can trivially derive Copy for the layout"); diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index 5839f9ed..9210148a 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -146,7 +146,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { if item.is_opaque(self.ctx, &()) { let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_debug() + l.opaque().can_trivially_derive_debug(self.ctx) }); return if layout_can_derive && !(ty.is_union() && @@ -242,7 +242,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { } if ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_debug() + l.opaque().can_trivially_derive_debug(self.ctx) }) { trace!(" union layout can trivially derive Debug"); @@ -299,7 +299,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { - if !sig.can_trivially_derive_debug() { + if !sig.can_trivially_derive_debug(self.ctx) { trace!( " function pointer that can't trivially derive Debug" ); diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index cc322e9b..2ff07ce9 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -173,7 +173,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { if item.is_opaque(self.ctx, &()) { let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_default() + l.opaque().can_trivially_derive_default(self.ctx) }); return if layout_can_derive && !(ty.is_union() && @@ -278,7 +278,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { } if ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_default() + l.opaque().can_trivially_derive_default(self.ctx) }) { trace!(" union layout can trivially derive Default"); diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 18c14a31..eee6d6f0 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -133,7 +133,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { if item.is_opaque(self.ctx, &()) { let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_hash() + l.opaque().can_trivially_derive_hash(self.ctx) }); return if layout_can_derive && !(ty.is_union() && @@ -218,7 +218,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { - if !sig.can_trivially_derive_hash() { + if !sig.can_trivially_derive_hash(self.ctx) { trace!( " function pointer that can't trivially derive Hash" ); @@ -230,7 +230,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { } TypeKind::Function(ref sig) => { - if !sig.can_trivially_derive_hash() { + if !sig.can_trivially_derive_hash(self.ctx) { trace!(" function that can't trivially derive Hash"); return self.insert(id); } @@ -275,7 +275,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { } if ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_hash() + l.opaque().can_trivially_derive_hash(self.ctx) }) { trace!(" union layout can trivially derive Hash"); diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs index c643a90b..5a9a21c5 100644 --- a/src/ir/analysis/derive_partialeq_or_partialord.rs +++ b/src/ir/analysis/derive_partialeq_or_partialord.rs @@ -129,7 +129,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { let layout_can_derive = ty.layout(self.ctx) .map_or(CanDerive::Yes, |l| { - l.opaque().can_trivially_derive_partialeq_or_partialord() + l.opaque().can_trivially_derive_partialeq_or_partialord(self.ctx) }); match layout_can_derive { @@ -210,7 +210,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { - if sig.can_trivially_derive_partialeq_or_partialord() + if sig.can_trivially_derive_partialeq_or_partialord(self.ctx) != CanDerive::Yes { trace!( @@ -224,7 +224,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { } TypeKind::Function(ref sig) => { - if sig.can_trivially_derive_partialeq_or_partialord() + if sig.can_trivially_derive_partialeq_or_partialord(self.ctx) != CanDerive::Yes { trace!( @@ -258,7 +258,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { let layout_can_derive = ty.layout(self.ctx).map_or(CanDerive::Yes, |l| { l.opaque() - .can_trivially_derive_partialeq_or_partialord() + .can_trivially_derive_partialeq_or_partialord(self.ctx) }); match layout_can_derive { CanDerive::Yes => { diff --git a/src/ir/context.rs b/src/ir/context.rs index bd353a5f..3f69aca1 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -226,7 +226,7 @@ where } } -impl<'a, T> CanDeriveCopy<'a> for T +impl<T> CanDeriveCopy for T where T: Copy + Into<ItemId> { diff --git a/src/ir/derive.rs b/src/ir/derive.rs index 65c22158..71854d2e 100644 --- a/src/ir/derive.rs +++ b/src/ir/derive.rs @@ -30,15 +30,15 @@ pub trait CanDeriveDebug { pub trait CanTriviallyDeriveDebug { /// Return `true` if `Debug` can trivially be derived for this thing, /// `false` otherwise. - fn can_trivially_derive_debug(&self) -> bool; + fn can_trivially_derive_debug(&self, ctx: &BindgenContext) -> bool; } /// A trait that encapsulates the logic for whether or not we can derive `Copy` /// for a given thing. -pub trait CanDeriveCopy<'a> { +pub trait CanDeriveCopy { /// Return `true` if `Copy` can be derived for this thing, `false` /// otherwise. - fn can_derive_copy(&'a self, ctx: &'a BindgenContext) -> bool; + fn can_derive_copy(&self, ctx: &BindgenContext) -> bool; } /// A trait that encapsulates the logic for whether or not we can trivially @@ -47,7 +47,7 @@ pub trait CanDeriveCopy<'a> { pub trait CanTriviallyDeriveCopy { /// Return `true` if `Copy` can be trivially derived for this thing, `false` /// otherwise. - fn can_trivially_derive_copy(&self) -> bool; + fn can_trivially_derive_copy(&self, ctx: &BindgenContext) -> bool; } /// A trait that encapsulates the logic for whether or not we can derive @@ -64,7 +64,7 @@ pub trait CanDeriveDefault { pub trait CanTriviallyDeriveDefault { /// Return `true` if `Default` can trivially derived for this thing, `false` /// otherwise. - fn can_trivially_derive_default(&self) -> bool; + fn can_trivially_derive_default(&self, ctx: &BindgenContext) -> bool; } /// A trait that encapsulates the logic for whether or not we can derive `Hash` @@ -111,7 +111,7 @@ pub trait CanDeriveOrd { pub trait CanTriviallyDeriveHash { /// Return `true` if `Hash` can trivially be derived for this thing, `false` /// otherwise. - fn can_trivially_derive_hash(&self) -> bool; + fn can_trivially_derive_hash(&self, ctx: &BindgenContext) -> bool; } /// A trait that encapsulates the logic for whether or not we can trivially @@ -120,11 +120,11 @@ pub trait CanTriviallyDeriveHash { pub trait CanTriviallyDerivePartialEqOrPartialOrd { /// Return `Yes` if `PartialEq` or `PartialOrd` can trivially be derived /// for this thing. - fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive; + fn can_trivially_derive_partialeq_or_partialord(&self, ctx: &BindgenContext) -> CanDerive; } /// Whether it is possible or not to automatically derive trait for an item. -/// +/// /// ```ignore /// No /// ^ @@ -134,7 +134,7 @@ pub trait CanTriviallyDerivePartialEqOrPartialOrd { /// | /// Yes /// ``` -/// +/// /// Initially we assume that we can derive trait for all types and then /// update our understanding as we learn more about each type. #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord)] @@ -144,7 +144,7 @@ pub enum CanDerive { /// The only thing that stops us from automatically deriving is that /// array with more than maximum number of elements is used. - /// + /// /// This means we probably can "manually" implement such trait. ArrayTooLarge, diff --git a/src/ir/function.rs b/src/ir/function.rs index 5e8d2fc8..f7f4398b 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -581,26 +581,23 @@ impl Trace for FunctionSig { } impl CanTriviallyDeriveDebug for FunctionSig { - fn can_trivially_derive_debug(&self) -> bool { + fn can_trivially_derive_debug(&self, _: &BindgenContext) -> bool { self.function_pointers_can_derive() } } impl CanTriviallyDeriveHash for FunctionSig { - fn can_trivially_derive_hash(&self) -> bool { + fn can_trivially_derive_hash(&self, _: &BindgenContext) -> bool { self.function_pointers_can_derive() } } impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig { - fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive { - if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT { - return CanDerive::No; - } - - match self.abi { - Abi::C | Abi::Unknown(..) => CanDerive::Yes, - _ => CanDerive::No, + fn can_trivially_derive_partialeq_or_partialord(&self, _: &BindgenContext) -> CanDerive { + if self.function_pointers_can_derive() { + CanDerive::Yes + } else { + CanDerive::No } } } diff --git a/src/ir/item.rs b/src/ir/item.rs index a7ced3d0..27e3d2f8 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -329,7 +329,7 @@ impl CanDeriveDefault for Item { } } -impl<'a> CanDeriveCopy<'a> for Item { +impl CanDeriveCopy for Item { fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { self.id().can_derive_copy(ctx) } diff --git a/src/ir/layout.rs b/src/ir/layout.rs index aa7dc566..c34da0e1 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -36,8 +36,12 @@ fn test_layout_for_size() { impl Layout { /// Gets the integer type name for a given known size. - pub fn known_type_for_size(size: usize) -> Option<&'static str> { + pub fn known_type_for_size( + ctx: &BindgenContext, + size: usize, + ) -> Option<&'static str> { Some(match size { + 16 if ctx.options().rust_features.i128_and_u128 => "u128", 8 => "u64", 4 => "u32", 2 => "u16", @@ -105,14 +109,14 @@ impl Opaque { /// Return the known rust type we should use to create a correctly-aligned /// field with this layout. - pub fn known_rust_type_for_array(&self) -> Option<&'static str> { - Layout::known_type_for_size(self.0.align) + pub fn known_rust_type_for_array(&self,ctx: &BindgenContext) -> Option<&'static str> { + Layout::known_type_for_size(ctx, self.0.align) } /// Return the array size that an opaque type for this layout should have if /// we know the correct type for it, or `None` otherwise. - pub fn array_size(&self) -> Option<usize> { - if self.known_rust_type_for_array().is_some() { + pub fn array_size(&self, ctx: &BindgenContext) -> Option<usize> { + if self.known_rust_type_for_array(ctx).is_some() { Some(self.0.size / cmp::max(self.0.align, 1)) } else { None @@ -122,45 +126,45 @@ impl Opaque { /// Return `true` if this opaque layout's array size will fit within the /// maximum number of array elements that Rust allows deriving traits /// with. Return `false` otherwise. - pub fn array_size_within_derive_limit(&self) -> bool { - self.array_size().map_or(false, |size| { + pub fn array_size_within_derive_limit(&self, ctx: &BindgenContext) -> bool { + self.array_size(ctx).map_or(false, |size| { size <= RUST_DERIVE_IN_ARRAY_LIMIT }) } } impl CanTriviallyDeriveDebug for Opaque { - fn can_trivially_derive_debug(&self) -> bool { - self.array_size_within_derive_limit() + fn can_trivially_derive_debug(&self, ctx: &BindgenContext) -> bool { + self.array_size_within_derive_limit(ctx) } } impl CanTriviallyDeriveDefault for Opaque { - fn can_trivially_derive_default(&self) -> bool { - self.array_size_within_derive_limit() + fn can_trivially_derive_default(&self, ctx: &BindgenContext) -> bool { + self.array_size_within_derive_limit(ctx) } } impl CanTriviallyDeriveCopy for Opaque { - fn can_trivially_derive_copy(&self) -> bool { - self.array_size_within_derive_limit() + fn can_trivially_derive_copy(&self, ctx: &BindgenContext) -> bool { + self.array_size_within_derive_limit(ctx) } } impl CanTriviallyDeriveHash for Opaque { - fn can_trivially_derive_hash(&self) -> bool { - self.array_size_within_derive_limit() + fn can_trivially_derive_hash(&self, ctx: &BindgenContext) -> bool { + self.array_size_within_derive_limit(ctx) } } impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque { - fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive { - self.array_size().map_or(CanDerive::No, |size| { - if size <= RUST_DERIVE_IN_ARRAY_LIMIT { - CanDerive::Yes - } else { - CanDerive::ArrayTooLarge - } - }) + fn can_trivially_derive_partialeq_or_partialord(&self, ctx: &BindgenContext) -> CanDerive { + // TODO(emilio): This is inconsistent with the rest of the + // CanTriviallyDerive* traits. + if self.array_size_within_derive_limit(ctx) { + CanDerive::Yes + } else { + CanDerive::ArrayTooLarge + } } } |