diff options
-rwxr-xr-x | src/clang.rs | 62 | ||||
-rw-r--r-- | src/ir/enum_ty.rs | 15 | ||||
-rw-r--r-- | src/ir/item.rs | 11 | ||||
-rw-r--r-- | src/ir/ty.rs | 9 |
4 files changed, 58 insertions, 39 deletions
diff --git a/src/clang.rs b/src/clang.rs index bfe0cfd3..c6af517c 100755 --- a/src/clang.rs +++ b/src/clang.rs @@ -101,7 +101,9 @@ impl Cursor { /// See documentation for `lexical_parent` for details on semantic vs /// lexical parents. pub fn fallible_semantic_parent(&self) -> Option<Cursor> { - let sp = self.semantic_parent(); + let sp = unsafe { + Cursor { x: clang_getCursorSemanticParent(self.x) } + }; if sp == *self || !sp.is_valid() { return None; } @@ -113,11 +115,7 @@ impl Cursor { /// See documentation for `lexical_parent` for details on semantic vs /// lexical parents. pub fn semantic_parent(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getCursorSemanticParent(self.x), - } - } + self.fallible_semantic_parent().unwrap() } /// Return the number of template arguments used by this cursor's referent, @@ -157,17 +155,18 @@ impl Cursor { /// Is the referent a top level construct? pub fn is_toplevel(&self) -> bool { - let mut semantic_parent = self.semantic_parent(); + let mut semantic_parent = self.fallible_semantic_parent(); - while semantic_parent.kind() == CXCursor_Namespace || - semantic_parent.kind() == CXCursor_NamespaceAlias || - semantic_parent.kind() == CXCursor_NamespaceRef { - semantic_parent = semantic_parent.semantic_parent(); + while semantic_parent.is_some() && + (semantic_parent.unwrap().kind() == CXCursor_Namespace || + semantic_parent.unwrap().kind() == CXCursor_NamespaceAlias || + semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) { + semantic_parent = semantic_parent.unwrap().fallible_semantic_parent(); } let tu = self.translation_unit(); - // Yes, the second can happen with, e.g., macro definitions. - semantic_parent == tu || semantic_parent == tu.semantic_parent() + // Yes, this can happen with, e.g., macro definitions. + semantic_parent == tu.fallible_semantic_parent() } /// Get the kind of referent this cursor is pointing to. @@ -349,20 +348,28 @@ impl Cursor { /// Get the signed constant value for this cursor's enum variant referent. /// - /// Returns `LLONG_MIN` if the cursor's referent is not an enum variant, - /// which is also a valid enum value, so callers should check the cursor - /// kind before calling this method (see issue #127). - pub fn enum_val_signed(&self) -> i64 { - unsafe { clang_getEnumConstantDeclValue(self.x) as i64 } + /// Returns None if the cursor's referent is not an enum variant. + pub fn enum_val_signed(&self) -> Option<i64> { + unsafe { + if self.kind() == CXCursor_EnumConstantDecl { + Some(clang_getEnumConstantDeclValue(self.x) as i64) + } else { + None + } + } } /// Get the unsigned constant value for this cursor's enum variant referent. /// - /// Returns `ULLONG_MAX` if the cursor's referent is not an enum variant, - /// which is also a valid enum value, so callers should check the cursor - /// kind before calling this method (see issue #128). - pub fn enum_val_unsigned(&self) -> u64 { - unsafe { clang_getEnumConstantDeclUnsignedValue(self.x) as u64 } + /// Returns None if the cursor's referent is not an enum variant. + pub fn enum_val_unsigned(&self) -> Option<u64> { + unsafe { + if self.kind() == CXCursor_EnumConstantDecl { + Some(clang_getEnumConstantDeclUnsignedValue(self.x) as u64) + } else { + None + } + } } /// Given that this cursor's referent is a `typedef`, get the `Type` that is @@ -444,15 +451,6 @@ impl Cursor { pub fn is_virtual_base(&self) -> bool { unsafe { clang_isVirtualBase(self.x) != 0 } } - - /// Given that this cursor's referent is a template specialization or - /// declaration, get the `i`th template argument kind. - /// - /// If the referent is not a template or `i` is out of bounds, an invalid - /// kind is returned. - pub fn template_arg_kind(&self, i: c_int) -> CXTemplateArgumentKind { - unsafe { clang_Cursor_getTemplateArgumentKind(self.x, i as c_uint) } - } } extern "C" fn visit_children<Visitor>(cur: CXCursor, diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index e78184e7..8efd9e3b 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -72,18 +72,19 @@ impl Enum { declaration.visit(|cursor| { if cursor.kind() == CXCursor_EnumConstantDecl { - let name = cursor.spelling(); - let comment = cursor.raw_comment(); - let val = if is_signed { - EnumVariantValue::Signed(cursor.enum_val_signed()) + let value = if is_signed { + cursor.enum_val_signed().map(EnumVariantValue::Signed) } else { - EnumVariantValue::Unsigned(cursor.enum_val_unsigned()) + cursor.enum_val_unsigned().map(EnumVariantValue::Unsigned) }; - variants.push(EnumVariant::new(name, comment, val)); + if let Some(val) = value { + let name = cursor.spelling(); + let comment = cursor.raw_comment(); + variants.push(EnumVariant::new(name, comment, val)); + } } CXChildVisit_Continue }); - Ok(Enum::new(repr, variants)) } } diff --git a/src/ir/item.rs b/src/ir/item.rs index a07ee1f3..c6d80a08 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -331,6 +331,12 @@ impl Item { self.kind().expect_type() } + /// Get a reference to this item's underlying `Type`, or `None` if this is + /// some other kind of item. + pub fn as_type(&self) -> Option<&Type> { + self.kind().as_type() + } + /// Get a reference to this item's underlying `Function`. Panic if this is /// some other kind of item. pub fn expect_function(&self) -> &Function { @@ -531,6 +537,11 @@ impl Item { ctx.opaque_by_name(&self.real_canonical_name(ctx, false, true)) } + /// Is this a reference to another type? + pub fn is_type_ref(&self) -> bool { + self.as_type().map_or(false, |ty| ty.is_type_ref()) + } + /// Get the canonical name without taking into account the replaces /// annotation. /// diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 78c2d459..77dc61be 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -136,6 +136,15 @@ impl Type { self.is_const } + /// Is this a reference to another type? + pub fn is_type_ref(&self) -> bool { + match self.kind { + TypeKind::ResolvedTypeRef(_) | + TypeKind::UnresolvedTypeRef(_, _, _) => true, + _ => false, + } + } + /// What is the layout of this type? pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> { use std::mem; |