diff options
-rw-r--r-- | bindgen-integration/cpp/Test.h | 6 | ||||
-rw-r--r-- | src/codegen/mod.rs | 6 | ||||
-rw-r--r-- | src/ir/context.rs | 7 | ||||
-rw-r--r-- | src/ir/int.rs | 15 | ||||
-rw-r--r-- | src/ir/layout.rs | 19 |
5 files changed, 41 insertions, 12 deletions
diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index e09c9ee7..8b9ad8d5 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -2,6 +2,8 @@ #define TESTMACRO +#include <cwchar> + enum { MY_ANNOYING_MACRO = #define MY_ANNOYING_MACRO 1 @@ -172,3 +174,7 @@ struct AutoRestoreBool { AutoRestoreBool(bool*); ~AutoRestoreBool(); }; + +struct WithWChar { + wchar_t foo[30]; +}; diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 026e9475..2a0891d9 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2978,6 +2978,12 @@ impl TryToRustTy for Type { IntKind::ULong => Ok(raw_type(ctx, "c_ulong")), 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) + .expect("Non-representable wchar_t?"); + let ident = ctx.rust_ident_raw(ty); + Ok(quote! { #ident }) + }, IntKind::I8 => Ok(quote! { i8 }), IntKind::U8 => Ok(quote! { u8 }), diff --git a/src/ir/context.rs b/src/ir/context.rs index 86dcda56..a85f70ba 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -2002,7 +2002,12 @@ impl BindgenContext { CXType_UChar => TypeKind::Int(IntKind::UChar), CXType_Short => TypeKind::Int(IntKind::Short), CXType_UShort => TypeKind::Int(IntKind::UShort), - CXType_WChar | CXType_Char16 => TypeKind::Int(IntKind::U16), + CXType_WChar => { + TypeKind::Int(IntKind::WChar { + size: ty.fallible_size().expect("Couldn't compute size of wchar_t?"), + }) + }, + CXType_Char16 => TypeKind::Int(IntKind::U16), CXType_Char32 => TypeKind::Int(IntKind::U32), CXType_Long => TypeKind::Int(IntKind::Long), CXType_ULong => TypeKind::Int(IntKind::ULong), diff --git a/src/ir/int.rs b/src/ir/int.rs index b7f0f0c5..144a7ded 100644 --- a/src/ir/int.rs +++ b/src/ir/int.rs @@ -12,6 +12,12 @@ pub enum IntKind { /// An `unsigned char`. UChar, + /// An `wchar_t`. + WChar { + /// The size of the wchar_t in bytes, which will be 2 or 4. + size: usize, + }, + /// A platform-dependent `char` type, with the signedness support. Char { /// Whether the char is signed for the target platform. @@ -87,15 +93,16 @@ impl IntKind { pub fn is_signed(&self) -> bool { use self::IntKind::*; match *self { + // TODO(emilio): wchar_t can in theory be signed, but we have no way + // to know whether it is or not right now (unlike char, there's no + // WChar_S / WChar_U). Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 | - U32 | U64 | U128 => false, + WChar { .. } | U32 | U64 | U128 => false, SChar | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 | I128 => true, - Char { - is_signed, - } => is_signed, + Char { is_signed } => is_signed, Custom { is_signed, .. diff --git a/src/ir/layout.rs b/src/ir/layout.rs index cca33cc3..aa7dc566 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -35,6 +35,17 @@ 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> { + Some(match size { + 8 => "u64", + 4 => "u32", + 2 => "u16", + 1 => "u8", + _ => return None, + }) + } + /// Construct a new `Layout` with the given `size` and `align`. It is not /// packed. pub fn new(size: usize, align: usize) -> Self { @@ -95,13 +106,7 @@ 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> { - Some(match self.0.align { - 8 => "u64", - 4 => "u32", - 2 => "u16", - 1 => "u8", - _ => return None, - }) + Layout::known_type_for_size(self.0.align) } /// Return the array size that an opaque type for this layout should have if |