summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindgen-integration/cpp/Test.h6
-rw-r--r--src/codegen/mod.rs6
-rw-r--r--src/ir/context.rs7
-rw-r--r--src/ir/int.rs15
-rw-r--r--src/ir/layout.rs19
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