diff options
author | Christian Legnitto <christian@legnitto.com> | 2019-01-07 20:06:34 -0800 |
---|---|---|
committer | Christian Legnitto <christian@legnitto.com> | 2019-01-08 08:56:19 -0800 |
commit | 3994a9a3a75245fcec59a2a3e62f163c1fa2e24b (patch) | |
tree | ba331e1ce2f9216896394783085003da86526ea8 /src | |
parent | 28c0eb4505865220d6f2a8f779f5876dc753feac (diff) |
Support #[repr(packed(N))] on Rust 1.33+
Fixes https://github.com/rust-lang/rust-bindgen/issues/537.
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen/helpers.rs | 3 | ||||
-rw-r--r-- | src/codegen/mod.rs | 5 | ||||
-rw-r--r-- | src/features.rs | 6 | ||||
-rw-r--r-- | src/ir/comp.rs | 23 |
4 files changed, 25 insertions, 12 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index d6377194..457979b6 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -7,6 +7,7 @@ use quote::TokenStreamExt; pub mod attributes { use proc_macro2::{Ident, Span, TokenStream}; + use std::str::FromStr; pub fn repr(which: &str) -> TokenStream { let which = Ident::new(which, Span::call_site()); @@ -16,7 +17,7 @@ pub mod attributes { } pub fn repr_list(which_ones: &[&str]) -> TokenStream { - let which_ones = which_ones.iter().cloned().map(|one| Ident::new(one, Span::call_site())); + let which_ones = which_ones.iter().cloned().map(|one| TokenStream::from_str(one).expect("repr to be valid")); quote! { #[repr( #( #which_ones ),* )] } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 6fd7e7d3..d3395edf 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1673,7 +1673,10 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::doc(comment)); } if packed && !is_opaque { - attributes.push(attributes::repr_list(&["C", "packed"])); + let n = layout.map_or(1, |l| l.align); + assert!(ctx.options().rust_features().repr_packed_n || n == 1); + let packed_repr = if n == 1 { "packed".to_string() } else { format!("packed({})", n) }; + attributes.push(attributes::repr_list(&["C", &packed_repr])); } else { attributes.push(attributes::repr("C")); } diff --git a/src/features.rs b/src/features.rs index 1f700039..b5a63402 100644 --- a/src/features.rs +++ b/src/features.rs @@ -102,6 +102,8 @@ macro_rules! rust_target_base { => Stable_1_27 => 1.27; /// Rust stable 1.28 => Stable_1_28 => 1.28; + /// Rust stable 1.33 + => Stable_1_33 => 1.33; /// Nightly rust => Nightly => nightly; ); @@ -190,6 +192,10 @@ rust_feature_def!( /// repr(transparent) ([PR](https://github.com/rust-lang/rust/pull/51562)) => repr_transparent; } + Stable_1_33 { + /// repr(packed(N)) ([PR](https://github.com/rust-lang/rust/pull/57049)) + => repr_packed_n; + } Nightly { /// `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202)) => thiscall_abi; diff --git a/src/ir/comp.rs b/src/ir/comp.rs index fd4c8274..12a8fa32 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1649,16 +1649,19 @@ impl IsOpaque for CompInfo { return true; } - // We don't have `#[repr(packed = "N")]` in Rust yet, so the best we can - // do is make this struct opaque. - // - // See https://github.com/rust-lang-nursery/rust-bindgen/issues/537 and - // https://github.com/rust-lang/rust/issues/33158 - if self.is_packed(ctx, layout) && layout.map_or(false, |l| l.align > 1) { - warn!("Found a type that is both packed and aligned to greater than \ - 1; Rust doesn't have `#[repr(packed = \"N\")]` yet, so we \ - are treating it as opaque"); - return true; + if !ctx.options().rust_features().repr_packed_n { + // If we don't have `#[repr(packed(N)]`, the best we can + // do is make this struct opaque. + // + // See https://github.com/rust-lang-nursery/rust-bindgen/issues/537 and + // https://github.com/rust-lang/rust/issues/33158 + if self.is_packed(ctx, layout) && layout.map_or(false, |l| l.align > 1) { + warn!("Found a type that is both packed and aligned to greater than \ + 1; Rust before version 1.33 doesn't have `#[repr(packed(N))]`, so we \ + are treating it as opaque. You may wish to set bindgen's rust target \ + version to 1.33 or later to enable `#[repr(packed(N))]` support."); + return true; + } } false |