summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/codegen/mod.rs6
-rw-r--r--libbindgen/src/ir/enum_ty.rs16
-rw-r--r--libbindgen/src/ir/int.rs15
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()