summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-10-15 01:39:03 +0200
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-10-18 15:56:14 +0200
commit2a3f93074dd2898669dbbce6e97e5cc4405d7cb1 (patch)
tree464ad46f18cdc2977291bcb161d0060184767fde
parent89406d7d7e3dbd3ef33d58b9bf5730d88d718cdf (diff)
ir: Test on typedefs also for template parameters that are transitively applicable before discarding them.
-rw-r--r--src/ir/item.rs17
-rw-r--r--tests/expectations/template_typedef_transitive_param.rs18
-rw-r--r--tests/headers/template_typedef_transitive_param.hpp7
3 files changed, 41 insertions, 1 deletions
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 1647dfe8..5b6297bd 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -167,6 +167,20 @@ impl Item {
self.kind().expect_function()
}
+ // This check is needed because even though the type might not contain the
+ // applicable template args itself, they might apply transitively via, for
+ // example, the parent.
+ //
+ // It's kind of unfortunate (in the sense that it's a sort of complex
+ // process, but I think it gets all the cases).
+ fn signature_contains_named_type(&self, ctx: &BindgenContext, ty: &Type) -> bool {
+ debug_assert!(ty.is_named());
+ self.expect_type().signature_contains_named_type(ctx, ty) ||
+ self.applicable_template_args(ctx).iter().any(|template| {
+ ctx.resolve_type(*template).signature_contains_named_type(ctx, ty)
+ })
+ }
+
pub fn applicable_template_args(&self, ctx: &BindgenContext) -> Vec<ItemId> {
let ty = match *self.kind() {
ItemKind::Type(ref ty) => ty,
@@ -197,7 +211,8 @@ impl Item {
TypeKind::Alias(_, inner) => {
let parent_args = ctx.resolve_item(self.parent_id())
.applicable_template_args(ctx);
- let inner = ctx.resolve_type(inner);
+ let inner = ctx.resolve_item(inner);
+
// Avoid unused type parameters, sigh.
parent_args.iter().cloned().filter(|arg| {
let arg = ctx.resolve_type(*arg);
diff --git a/tests/expectations/template_typedef_transitive_param.rs b/tests/expectations/template_typedef_transitive_param.rs
new file mode 100644
index 00000000..166ddc3c
--- /dev/null
+++ b/tests/expectations/template_typedef_transitive_param.rs
@@ -0,0 +1,18 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Wrapper<T> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Wrapper_Wrapped<T> {
+ pub t: T,
+}
+pub type Wrapper_Type<T> = Wrapper_Wrapped<T>;
diff --git a/tests/headers/template_typedef_transitive_param.hpp b/tests/headers/template_typedef_transitive_param.hpp
new file mode 100644
index 00000000..2269ac36
--- /dev/null
+++ b/tests/headers/template_typedef_transitive_param.hpp
@@ -0,0 +1,7 @@
+template<typename T>
+struct Wrapper {
+ struct Wrapped {
+ T t;
+ };
+ using Type = Wrapped;
+};