diff options
Diffstat (limited to 'libbindgen/src')
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 6 | ||||
-rw-r--r-- | libbindgen/src/ir/enum_ty.rs | 16 | ||||
-rw-r--r-- | libbindgen/src/ir/int.rs | 15 |
3 files changed, 26 insertions, 11 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index e9141b9c..6213a068 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -1562,7 +1562,11 @@ impl CodeGenerator for Enum { }; let signed = repr.is_signed(); - let size = layout.map(|l| l.size).unwrap_or(0); + let size = layout + .map(|l| l.size) + .or_else(|| repr.known_size()) + .unwrap_or(0); + let repr_name = match (signed, size) { (true, 1) => "i8", (false, 1) => "u8", diff --git a/libbindgen/src/ir/enum_ty.rs b/libbindgen/src/ir/enum_ty.rs index d7e4de09..b65d3c06 100644 --- a/libbindgen/src/ir/enum_ty.rs +++ b/libbindgen/src/ir/enum_ty.rs @@ -53,22 +53,18 @@ impl Enum { .and_then(|et| Item::from_ty(&et, None, None, ctx).ok()); let mut variants = vec![]; - let is_signed = match repr { - Some(repr) => { - let repr_type = ctx.resolve_type(repr); - match *repr_type.canonical_type(ctx).kind() { + // Assume signedness since the default type by the C standard is an int. + let is_signed = repr + .and_then(|r| ctx.resolve_type(r).safe_canonical_type(ctx)) + .map_or(true, |ty| { + match *ty.kind() { TypeKind::Int(ref int_kind) => int_kind.is_signed(), ref other => { panic!("Since when enums can be non-integers? {:?}", other) } } - } - // Assume signedness since the default type by the C - // standard is an - // int. - None => true, - }; + }); declaration.visit(|cursor| { if cursor.kind() == CXCursor_EnumConstantDecl { diff --git a/libbindgen/src/ir/int.rs b/libbindgen/src/ir/int.rs index 179ebb96..89068e0f 100644 --- a/libbindgen/src/ir/int.rs +++ b/libbindgen/src/ir/int.rs @@ -91,6 +91,21 @@ impl IntKind { } } + /// If this type has a known size, return it (in bytes). This is to + /// alleviate libclang sometimes not giving us a layout (like in the case + /// when an enum is defined inside a class with template parameters). + pub fn known_size(&self) -> Option<usize> { + use self::IntKind::*; + Some(match *self { + Bool | UChar | Char | U8 | I8 => 1, + U16 | I16 => 2, + U32 | I32 => 4, + U64 | I64 => 8, + I128 | U128 => 16, + _ => return None, + }) + } + /// Whether this type's signedness matches the value. pub fn signedness_matches(&self, val: i64) -> bool { val >= 0 || self.is_signed() |