summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbindgen/src/ir/item.rs38
-rw-r--r--libbindgen/src/ir/ty.rs33
-rw-r--r--libbindgen/tests/expectations/tests/templateref_opaque.rs20
-rw-r--r--libbindgen/tests/headers/templateref_opaque.hpp11
4 files changed, 80 insertions, 22 deletions
diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs
index c370c8b0..32e3c4c5 100644
--- a/libbindgen/src/ir/item.rs
+++ b/libbindgen/src/ir/item.rs
@@ -1,6 +1,7 @@
//! Bindgen's core intermediate representation type.
use clang;
+use clangll;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use std::cell::{Cell, RefCell};
use std::fmt::Write;
@@ -733,6 +734,31 @@ impl Item {
}
}
+// An utility function to handle recursing inside nested types.
+fn visit_child(cur: clang::Cursor,
+ id: ItemId,
+ ty: &clang::Type,
+ parent_id: Option<ItemId>,
+ ctx: &mut BindgenContext,
+ result: &mut Result<ItemId, ParseError>)
+ -> clangll::Enum_CXChildVisitResult {
+ use clangll::*;
+ if result.is_ok() {
+ return CXChildVisit_Break;
+ }
+
+ *result = Item::from_ty_with_id(id, ty, Some(cur), parent_id, ctx);
+
+ match *result {
+ Ok(..) => CXChildVisit_Break,
+ Err(ParseError::Recurse) => {
+ cur.visit(|c| visit_child(c, id, ty, parent_id, ctx, result));
+ CXChildVisit_Continue
+ }
+ Err(ParseError::Continue) => CXChildVisit_Continue,
+ }
+}
+
impl ClangItemParser for Item {
fn builtin_type(kind: TypeKind,
is_const: bool,
@@ -1022,17 +1048,7 @@ impl ClangItemParser for Item {
}
location.visit(|cur| {
- use clangll::*;
- result = Item::from_ty_with_id(id,
- ty,
- Some(cur),
- parent_id,
- ctx);
- match result {
- Ok(..) => CXChildVisit_Break,
- Err(ParseError::Recurse) => CXChildVisit_Recurse,
- Err(ParseError::Continue) => CXChildVisit_Continue,
- }
+ visit_child(cur, id, ty, parent_id, ctx, &mut result)
});
if valid_decl {
diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs
index 60611b8d..7f01e388 100644
--- a/libbindgen/src/ir/ty.rs
+++ b/libbindgen/src/ir/ty.rs
@@ -685,30 +685,41 @@ impl Type {
CXCursor_TemplateRef => {
let referenced = location.referenced().unwrap();
let referenced_ty = referenced.cur_type();
- let referenced_declaration =
- Some(referenced_ty.declaration());
+
+ debug!("TemplateRef: location = {:?}; referenced = \
+ {:?}; referenced_ty = {:?}",
+ location,
+ referenced,
+ referenced_ty);
return Self::from_clang_ty(potential_id,
&referenced_ty,
- referenced_declaration,
+ Some(referenced),
parent_id,
ctx);
}
CXCursor_TypeRef => {
let referenced = location.referenced().unwrap();
let referenced_ty = referenced.cur_type();
- let referenced_declaration =
- Some(referenced_ty.declaration());
+ let declaration = referenced_ty.declaration();
+
+ debug!("TypeRef: location = {:?}; referenced = \
+ {:?}; referenced_ty = {:?}",
+ location,
+ referenced,
+ referenced_ty);
let item =
- Item::from_ty_or_ref_with_id(
- potential_id,
- referenced_ty,
- referenced_declaration,
- parent_id,
- ctx);
+ Item::from_ty_or_ref_with_id(potential_id,
+ referenced_ty,
+ Some(declaration),
+ parent_id,
+ ctx);
return Ok(ParseResult::AlreadyResolved(item));
}
+ CXCursor_NamespaceRef => {
+ return Err(ParseError::Continue);
+ }
_ => {
if ty.kind() == CXType_Unexposed {
warn!("Unexposed type {:?}, recursing inside, \
diff --git a/libbindgen/tests/expectations/tests/templateref_opaque.rs b/libbindgen/tests/expectations/tests/templateref_opaque.rs
new file mode 100644
index 00000000..d69254c8
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/templateref_opaque.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct detail_PointerType<T> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
+pub type detail_PointerType_Type<T> = *mut T;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct UniquePtr<T> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
+pub type UniquePtr_Pointer<T> = detail_PointerType<T>;
diff --git a/libbindgen/tests/headers/templateref_opaque.hpp b/libbindgen/tests/headers/templateref_opaque.hpp
new file mode 100644
index 00000000..ca154c34
--- /dev/null
+++ b/libbindgen/tests/headers/templateref_opaque.hpp
@@ -0,0 +1,11 @@
+
+namespace detail {
+template<typename T>
+struct PointerType {
+ typedef T* Type;
+};
+}
+template<typename T>
+class UniquePtr {
+ typedef typename detail::PointerType<T> Pointer;
+};