From b31fcb85f2c4c63a60c617b8d4c8c801444d6117 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 1 May 2017 10:02:38 -0700 Subject: 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 --- src/ir/comp.rs | 15 +++++-- src/ir/ty.rs | 1 + tests/expectations/tests/issue-674-1.rs | 46 ++++++++++++++++++++++ tests/expectations/tests/issue-674-2.rs | 69 +++++++++++++++++++++++++++++++++ tests/expectations/tests/issue-674-3.rs | 60 ++++++++++++++++++++++++++++ tests/headers/issue-674-1.hpp | 8 ++++ tests/headers/issue-674-2.hpp | 15 +++++++ tests/headers/issue-674-3.hpp | 11 ++++++ 8 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 tests/expectations/tests/issue-674-1.rs create mode 100644 tests/expectations/tests/issue-674-2.rs create mode 100644 tests/expectations/tests/issue-674-3.rs create mode 100644 tests/headers/issue-674-1.hpp create mode 100644 tests/headers/issue-674-2.hpp create mode 100644 tests/headers/issue-674-3.hpp 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; + 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::() , 1usize , + concat ! ( + "Size of: " , stringify ! ( CapturingContentInfo ) )); + assert_eq! (::std::mem::align_of::() , 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; + 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::() , 1usize , concat ! ( + "Size of: " , stringify ! ( c ) )); + assert_eq! (::std::mem::align_of::() , 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::() , 1usize , concat ! ( + "Size of: " , stringify ! ( B ) )); + assert_eq! (::std::mem::align_of::() , 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 = *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::() , 1usize , concat ! ( + "Size of: " , stringify ! ( a ) )); + assert_eq! (::std::mem::align_of::() , 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::() , 1usize , concat ! ( + "Size of: " , stringify ! ( nsCSSValue ) )); + assert_eq! (::std::mem::align_of::() , 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 Maybe { using ValueType = T; }; +} +struct CapturingContentInfo { + mozilla::Maybe 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 class Rooted { using ElementType = T; }; +} +class c { + JS::Rooted b; +}; +class B { + c a; +}; +template class StaticRefPtr {}; +struct { + StaticRefPtr 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 nsRefPtrHashtable { + typedef PtrType *UserDataType; +}; +struct a { + nsRefPtrHashtable b; +}; +class nsCSSValue { + a c; +}; -- cgit v1.2.3