summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/codegen/mod.rs38
-rw-r--r--libbindgen/src/ir/item.rs11
-rw-r--r--libbindgen/src/ir/ty.rs14
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 {