diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-11-21 12:25:06 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-21 12:25:06 -0600 |
commit | c3ce5b1e3820f691856bf4c66890646c67676679 (patch) | |
tree | 333293aeff242aaa0c4319bd07eb1c544173560d | |
parent | fc93c36139ae40242c782a153f6b2252317c72cd (diff) | |
parent | f522b613b899e70a6141375dd46da1a6f49db360 (diff) |
Auto merge of #288 - emilio:stylo-bustage, r=fitzgen
Better handling of derived types inside namespaces.
Not perfect, since for example we can never arrive to the `Type` typedef it seems, but it doesn't generate invalid code, and we handle correctly the non-dependent types.
r? @fitzgen
-rw-r--r-- | libbindgen/src/ir/item.rs | 38 | ||||
-rw-r--r-- | libbindgen/src/ir/ty.rs | 33 | ||||
-rw-r--r-- | libbindgen/tests/expectations/tests/templateref_opaque.rs | 20 | ||||
-rw-r--r-- | libbindgen/tests/headers/templateref_opaque.hpp | 11 |
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; +}; |