summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-05-01 10:02:38 -0700
committerNick Fitzgerald <fitzgen@gmail.com>2017-05-01 10:19:36 -0700
commitb31fcb85f2c4c63a60c617b8d4c8c801444d6117 (patch)
treecd6ae381eafa8df071d3b5c63575bab73fb84848
parentaf613b1c40ed9d97bb8c636488708723cfd56898 (diff)
Trace opaque types' template parameters and inner types
The template parameter usage analysis needs to see the template parameters' definitions and have edges from any inner type to the parent in order to propagate data flow through dependencies properly. Fixes #674
-rw-r--r--src/ir/comp.rs15
-rw-r--r--src/ir/ty.rs1
-rw-r--r--tests/expectations/tests/issue-674-1.rs46
-rw-r--r--tests/expectations/tests/issue-674-2.rs69
-rw-r--r--tests/expectations/tests/issue-674-3.rs60
-rw-r--r--tests/headers/issue-674-1.hpp8
-rw-r--r--tests/headers/issue-674-2.hpp15
-rw-r--r--tests/headers/issue-674-3.hpp11
8 files changed, 221 insertions, 4 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 2711c3cf..91593b79 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -975,6 +975,17 @@ impl Trace for CompInfo {
tracer.visit_kind(p, EdgeKind::TemplateParameterDefinition);
}
+ for &ty in self.inner_types() {
+ tracer.visit_kind(ty, EdgeKind::InnerType);
+ }
+
+ // We unconditionally trace `CompInfo`'s template parameters and inner
+ // types for the the usage analysis. However, we don't want to continue
+ // tracing anything else, if this type is marked opaque.
+ if item.is_opaque(context) {
+ return;
+ }
+
for base in self.base_members() {
tracer.visit_kind(base.ty, EdgeKind::BaseMember);
}
@@ -983,10 +994,6 @@ impl Trace for CompInfo {
tracer.visit_kind(field.ty(), EdgeKind::Field);
}
- for &ty in self.inner_types() {
- tracer.visit_kind(ty, EdgeKind::InnerType);
- }
-
for &var in self.inner_vars() {
tracer.visit_kind(var, EdgeKind::InnerVar);
}
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 9fabf980..c3f26572 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -345,6 +345,7 @@ impl Type {
/// 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::Comp(..) |
TypeKind::Function(..) |
TypeKind::Pointer(..) |
TypeKind::Array(..) |
diff --git a/tests/expectations/tests/issue-674-1.rs b/tests/expectations/tests/issue-674-1.rs
new file mode 100644
index 00000000..8be8721c
--- /dev/null
+++ b/tests/expectations/tests/issue-674-1.rs
@@ -0,0 +1,46 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ pub mod mozilla {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ #[repr(C)]
+ #[derive(Debug, Copy, Clone)]
+ pub struct Maybe {
+ pub _address: u8,
+ }
+ pub type Maybe_ValueType<T> = T;
+ impl Default for Maybe {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ }
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct CapturingContentInfo {
+ pub a: u8,
+ }
+ #[test]
+ fn bindgen_test_layout_CapturingContentInfo() {
+ assert_eq!(::std::mem::size_of::<CapturingContentInfo>() , 1usize ,
+ concat ! (
+ "Size of: " , stringify ! ( CapturingContentInfo ) ));
+ assert_eq! (::std::mem::align_of::<CapturingContentInfo>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( CapturingContentInfo ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const CapturingContentInfo ) ) . a as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! (
+ CapturingContentInfo ) , "::" , stringify ! ( a ) ));
+ }
+ impl Clone for CapturingContentInfo {
+ fn clone(&self) -> Self { *self }
+ }
+}
diff --git a/tests/expectations/tests/issue-674-2.rs b/tests/expectations/tests/issue-674-2.rs
new file mode 100644
index 00000000..1f597c9e
--- /dev/null
+++ b/tests/expectations/tests/issue-674-2.rs
@@ -0,0 +1,69 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ pub mod JS {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ #[repr(C)]
+ #[derive(Debug, Copy, Clone)]
+ pub struct Rooted {
+ pub _address: u8,
+ }
+ pub type Rooted_ElementType<T> = T;
+ impl Default for Rooted {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ }
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct c {
+ pub b: u8,
+ }
+ #[test]
+ fn bindgen_test_layout_c() {
+ assert_eq!(::std::mem::size_of::<c>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( c ) ));
+ assert_eq! (::std::mem::align_of::<c>() , 1usize , concat ! (
+ "Alignment of " , stringify ! ( c ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const c ) ) . b as * const _ as usize } ,
+ 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( c ) , "::" ,
+ stringify ! ( b ) ));
+ }
+ impl Clone for c {
+ fn clone(&self) -> Self { *self }
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct B {
+ pub a: root::c,
+ }
+ #[test]
+ fn bindgen_test_layout_B() {
+ assert_eq!(::std::mem::size_of::<B>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( B ) ));
+ assert_eq! (::std::mem::align_of::<B>() , 1usize , concat ! (
+ "Alignment of " , stringify ! ( B ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const B ) ) . a as * const _ as usize } ,
+ 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( B ) , "::" ,
+ stringify ! ( a ) ));
+ }
+ impl Clone for B {
+ fn clone(&self) -> Self { *self }
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct StaticRefPtr {
+ pub _address: u8,
+ }
+}
diff --git a/tests/expectations/tests/issue-674-3.rs b/tests/expectations/tests/issue-674-3.rs
new file mode 100644
index 00000000..69587deb
--- /dev/null
+++ b/tests/expectations/tests/issue-674-3.rs
@@ -0,0 +1,60 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ #[repr(C)]
+ #[derive(Debug, Copy, Clone)]
+ pub struct nsRefPtrHashtable {
+ pub _address: u8,
+ }
+ pub type nsRefPtrHashtable_UserDataType<PtrType> = *mut PtrType;
+ impl Default for nsRefPtrHashtable {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct a {
+ pub b: u8,
+ }
+ #[test]
+ fn bindgen_test_layout_a() {
+ assert_eq!(::std::mem::size_of::<a>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( a ) ));
+ assert_eq! (::std::mem::align_of::<a>() , 1usize , concat ! (
+ "Alignment of " , stringify ! ( a ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const a ) ) . b as * const _ as usize } ,
+ 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( a ) , "::" ,
+ stringify ! ( b ) ));
+ }
+ impl Clone for a {
+ fn clone(&self) -> Self { *self }
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct nsCSSValue {
+ pub c: root::a,
+ }
+ #[test]
+ fn bindgen_test_layout_nsCSSValue() {
+ assert_eq!(::std::mem::size_of::<nsCSSValue>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( nsCSSValue ) ));
+ assert_eq! (::std::mem::align_of::<nsCSSValue>() , 1usize , concat ! (
+ "Alignment of " , stringify ! ( nsCSSValue ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const nsCSSValue ) ) . c as * const _ as
+ usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( nsCSSValue ) , "::"
+ , stringify ! ( c ) ));
+ }
+ impl Clone for nsCSSValue {
+ fn clone(&self) -> Self { *self }
+ }
+}
diff --git a/tests/headers/issue-674-1.hpp b/tests/headers/issue-674-1.hpp
new file mode 100644
index 00000000..f5c05917
--- /dev/null
+++ b/tests/headers/issue-674-1.hpp
@@ -0,0 +1,8 @@
+// bindgen-flags: --enable-cxx-namespaces --whitelist-type CapturingContentInfo --opaque-type 'mozilla::Maybe' -- -- -std=c++14
+
+namespace mozilla {
+template <class T> class Maybe { using ValueType = T; };
+}
+struct CapturingContentInfo {
+ mozilla::Maybe<float> a;
+};
diff --git a/tests/headers/issue-674-2.hpp b/tests/headers/issue-674-2.hpp
new file mode 100644
index 00000000..5f65a05b
--- /dev/null
+++ b/tests/headers/issue-674-2.hpp
@@ -0,0 +1,15 @@
+// bindgen-flags: --enable-cxx-namespaces --whitelist-type StaticRefPtr --opaque-type 'JS::Rooted' -- -- -std=c++14
+
+namespace JS {
+template <typename T> class Rooted { using ElementType = T; };
+}
+class c {
+ JS::Rooted<int> b;
+};
+class B {
+ c a;
+};
+template <class> class StaticRefPtr {};
+struct {
+ StaticRefPtr<B> d;
+} e;
diff --git a/tests/headers/issue-674-3.hpp b/tests/headers/issue-674-3.hpp
new file mode 100644
index 00000000..c1bd2f32
--- /dev/null
+++ b/tests/headers/issue-674-3.hpp
@@ -0,0 +1,11 @@
+// bindgen-flags: --enable-cxx-namespaces --whitelist-type nsCSSValue --opaque-type 'nsRefPtrHashtable' -- -- -std=c++14
+
+template <class PtrType> class nsRefPtrHashtable {
+ typedef PtrType *UserDataType;
+};
+struct a {
+ nsRefPtrHashtable<int> b;
+};
+class nsCSSValue {
+ a c;
+};