summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindgen-integration/cpp/Test.cc12
-rw-r--r--bindgen-integration/cpp/Test.h13
-rwxr-xr-xbindgen-integration/src/lib.rs19
-rw-r--r--src/codegen/mod.rs23
-rw-r--r--src/ir/function.rs11
-rw-r--r--tests/expectations/tests/issue-946.rs21
-rw-r--r--tests/expectations/tests/virtual_dtor.rs4
-rw-r--r--tests/headers/issue-946.h5
8 files changed, 95 insertions, 13 deletions
diff --git a/bindgen-integration/cpp/Test.cc b/bindgen-integration/cpp/Test.cc
index 57c2186b..80ae0239 100644
--- a/bindgen-integration/cpp/Test.cc
+++ b/bindgen-integration/cpp/Test.cc
@@ -3,6 +3,18 @@
const int Test::COUNTDOWN[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const int* Test::COUNTDOWN_PTR = Test::COUNTDOWN;
+unsigned VirtualDestructor::sDestructorCount = 0;
+VirtualDestructor::~VirtualDestructor() {
+ sDestructorCount++;
+}
+
+unsigned InheritsFromVirtualDestructor::sDestructorCount = 0;
+InheritsFromVirtualDestructor::InheritsFromVirtualDestructor() = default;
+
+InheritsFromVirtualDestructor::~InheritsFromVirtualDestructor() {
+ sDestructorCount++;
+}
+
const int* Test::countdown() {
return COUNTDOWN;
}
diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h
index 4ab8373e..323a9216 100644
--- a/bindgen-integration/cpp/Test.h
+++ b/bindgen-integration/cpp/Test.h
@@ -19,6 +19,19 @@ class ITest {
virtual void foo() = 0;
};
+class VirtualDestructor {
+public:
+ static unsigned sDestructorCount;
+ virtual ~VirtualDestructor() = 0;
+};
+
+class InheritsFromVirtualDestructor final : public VirtualDestructor {
+public:
+ static unsigned sDestructorCount;
+ InheritsFromVirtualDestructor();
+ ~InheritsFromVirtualDestructor() final;
+};
+
namespace testing {
typedef Test TypeAlias;
diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs
index 3c3652d9..176da3bb 100755
--- a/bindgen-integration/src/lib.rs
+++ b/bindgen-integration/src/lib.rs
@@ -260,3 +260,22 @@ fn test_destructors() {
assert!(v, "Should've been restored when going out of scope");
}
+
+impl Drop for bindings::InheritsFromVirtualDestructor {
+ fn drop(&mut self) {
+ unsafe { bindings::InheritsFromVirtualDestructor_InheritsFromVirtualDestructor_destructor(self) }
+ }
+}
+
+#[test]
+fn test_virtual_dtor() {
+ unsafe {
+ {
+ let b = bindings::InheritsFromVirtualDestructor::new();
+ // Let it go out of scope.
+ }
+
+ assert_eq!(bindings::InheritsFromVirtualDestructor_sDestructorCount, 1);
+ assert_eq!(bindings::VirtualDestructor_sDestructorCount, 1);
+ }
+}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 79e63de6..0ddcdc0a 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -614,14 +614,20 @@ impl CodeGenerator for Type {
.resolve(ctx);
let name = item.canonical_name(ctx);
- // Try to catch the common pattern:
- //
- // typedef struct foo { ... } foo;
- //
- // here.
- //
- if inner_item.canonical_name(ctx) == name {
- return;
+ {
+ let through_type_aliases = inner.into_resolver()
+ .through_type_refs()
+ .through_type_aliases()
+ .resolve(ctx);
+
+ // Try to catch the common pattern:
+ //
+ // typedef struct foo { ... } foo;
+ //
+ // here, and also other more complex cases like #946.
+ if through_type_aliases.canonical_name(ctx) == name {
+ return;
+ }
}
// If this is a known named type, disallow generating anything
@@ -1969,6 +1975,7 @@ impl MethodCodegen for Method {
}
});
+ // TODO(emilio): We could generate final stuff at least.
if self.is_virtual() {
return; // FIXME
}
diff --git a/src/ir/function.rs b/src/ir/function.rs
index b39c92b7..f027e47c 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -245,6 +245,7 @@ pub fn cursor_mangling(
cursor: &clang::Cursor,
) -> Option<String> {
use clang_sys;
+
if !ctx.options().enable_mangling {
return None;
}
@@ -256,8 +257,14 @@ pub fn cursor_mangling(
return None;
}
+ let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor;
if let Ok(mut manglings) = cursor.cxx_manglings() {
- if let Some(m) = manglings.pop() {
+ while let Some(m) = manglings.pop() {
+ // Only generate the destructor group 1, see below.
+ if is_destructor && !m.ends_with("D1Ev") {
+ continue;
+ }
+
return Some(m);
}
}
@@ -267,7 +274,7 @@ pub fn cursor_mangling(
return None;
}
- if cursor.kind() == clang_sys::CXCursor_Destructor {
+ if is_destructor {
// With old (3.8-) libclang versions, and the Itanium ABI, clang returns
// the "destructor group 0" symbol, which means that it'll try to free
// memory, which definitely isn't what we want.
diff --git a/tests/expectations/tests/issue-946.rs b/tests/expectations/tests/issue-946.rs
new file mode 100644
index 00000000..14ed38c6
--- /dev/null
+++ b/tests/expectations/tests/issue-946.rs
@@ -0,0 +1,21 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct foo {}
+#[test]
+fn bindgen_test_layout_foo() {
+ assert_eq!(
+ ::std::mem::size_of::<foo>(),
+ 0usize,
+ concat!("Size of: ", stringify!(foo))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<foo>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(foo))
+ );
+}
+pub type bar = foo;
diff --git a/tests/expectations/tests/virtual_dtor.rs b/tests/expectations/tests/virtual_dtor.rs
index 72086053..91830908 100644
--- a/tests/expectations/tests/virtual_dtor.rs
+++ b/tests/expectations/tests/virtual_dtor.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
pub struct nsSlots__bindgen_vtable(::std::os::raw::c_void);
#[repr(C)]
@@ -30,6 +28,6 @@ impl Default for nsSlots {
}
}
extern "C" {
- #[link_name = "\u{1}_ZN7nsSlotsD0Ev"]
+ #[link_name = "\u{1}_ZN7nsSlotsD1Ev"]
pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots);
}
diff --git a/tests/headers/issue-946.h b/tests/headers/issue-946.h
new file mode 100644
index 00000000..5d145e09
--- /dev/null
+++ b/tests/headers/issue-946.h
@@ -0,0 +1,5 @@
+struct foo { };
+
+typedef struct foo bar;
+
+typedef bar foo;