diff options
Diffstat (limited to 'libbindgen/src')
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 38 | ||||
-rw-r--r-- | libbindgen/src/ir/item.rs | 11 | ||||
-rw-r--r-- | libbindgen/src/ir/ty.rs | 14 |
3 files changed, 41 insertions, 22 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 6e63a791..d12c3d2a 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -1879,7 +1879,13 @@ impl ToRustTy for Type { TypeKind::ResolvedTypeRef(inner) => inner.to_rust_ty(ctx), TypeKind::TemplateAlias(ref spelling, inner, _) | TypeKind::Alias(ref spelling, inner) => { - if item.is_opaque(ctx) { + let applicable_named_args = + item.applicable_template_args(ctx) + .into_iter() + .filter(|arg| ctx.resolve_type(*arg).is_named()) + .collect::<Vec<_>>(); + + if item.is_opaque(ctx) && !applicable_named_args.is_empty() { // Pray if there's no available layout. let layout = self.layout(ctx).unwrap_or_else(Layout::zero); BlobTyBuilder::new(layout).build() @@ -1888,11 +1894,15 @@ impl ToRustTy for Type { inner) { ty } else { - utils::build_templated_path(item, ctx, true) + utils::build_templated_path(item, + ctx, + applicable_named_args) } } TypeKind::Comp(ref info) => { - if item.is_opaque(ctx) || info.has_non_type_template_params() { + let template_args = item.applicable_template_args(ctx); + if info.has_non_type_template_params() || + (item.is_opaque(ctx) && !template_args.is_empty()) { return match self.layout(ctx) { Some(layout) => BlobTyBuilder::new(layout).build(), None => { @@ -1904,7 +1914,7 @@ impl ToRustTy for Type { }; } - utils::build_templated_path(item, ctx, false) + utils::build_templated_path(item, ctx, template_args) } TypeKind::BlockPointer => { let void = raw_type(ctx, "c_void"); @@ -2215,23 +2225,15 @@ mod utils { pub fn build_templated_path(item: &Item, ctx: &BindgenContext, - only_named: bool) + template_args: Vec<ItemId>) -> P<ast::Ty> { let path = item.namespace_aware_canonical_path(ctx); - let builder = aster::AstBuilder::new().ty().path(); - let template_args = if only_named { - item.applicable_template_args(ctx) - .iter() - .filter(|arg| ctx.resolve_type(**arg).is_named()) - .map(|arg| arg.to_rust_ty(ctx)) - .collect::<Vec<_>>() - } else { - item.applicable_template_args(ctx) - .iter() - .map(|arg| arg.to_rust_ty(ctx)) - .collect::<Vec<_>>() - }; + + let template_args = template_args + .iter() + .map(|arg| arg.to_rust_ty(ctx)) + .collect::<Vec<_>>(); // XXX: I suck at aster. if path.len() == 1 { diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs index f4598654..e9960166 100644 --- a/libbindgen/src/ir/item.rs +++ b/libbindgen/src/ir/item.rs @@ -190,14 +190,17 @@ impl TypeCollector for Item { match *self.kind() { ItemKind::Type(ref ty) => { - if !self.is_opaque(ctx) { + // There are some types, like resolved type references, where we + // don't want to stop collecting types even though they may be + // opaque. + if ty.should_be_traced_unconditionally() || !self.is_opaque(ctx) { ty.collect_types(ctx, types, self); } } ItemKind::Function(ref fun) => { - if !self.is_opaque(ctx) { - types.insert(fun.signature()); - } + // Just the same way, it has not real meaning for a function to + // be opaque, so we trace across it. + types.insert(fun.signature()); } _ => {} // FIXME. } diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs index df3baf91..e83ef4fd 100644 --- a/libbindgen/src/ir/ty.rs +++ b/libbindgen/src/ir/ty.rs @@ -316,6 +316,20 @@ impl Type { TypeKind::UnresolvedTypeRef(..) => None, } } + + /// There are some types we don't want to stop at when finding an opaque + /// item, so we can arrive to the proper item that needs to be generated. + pub fn should_be_traced_unconditionally(&self) -> bool { + match self.kind { + TypeKind::Function(..) | + TypeKind::Pointer(..) | + TypeKind::Array(..) | + TypeKind::Reference(..) | + TypeKind::TemplateRef(..) | + TypeKind::ResolvedTypeRef(..) => true, + _ => false, + } + } } impl CanDeriveDebug for Type { |