summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/clang.rs62
-rw-r--r--src/ir/enum_ty.rs15
-rw-r--r--src/ir/item.rs11
-rw-r--r--src/ir/ty.rs9
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;