summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/codegen/mod.rs22
-rw-r--r--tests/expectations/tests/c-empty-layout.rs20
-rw-r--r--tests/expectations/tests/cpp-empty-layout.rs21
-rw-r--r--tests/headers/c-empty-layout.h1
-rw-r--r--tests/headers/cpp-empty-layout.hpp1
6 files changed, 59 insertions, 8 deletions
diff --git a/README.md b/README.md
index f1a85cec..9c219ef5 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@ $ port install clang-3.9
##### Debian-based Linuxes
```
-# apt-get install llvm-3.9-dev libclang-3.9-dev
+# apt-get install llvm-3.9-dev libclang-3.9-dev clang-3.9
```
Ubuntu 16.10 provides the necessary packages directly. If you are using older
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 7bc8985b..7b7c31a8 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1287,17 +1287,25 @@ impl CodeGenerator for CompInfo {
}
}
- // C requires every struct to be addressable, so what C compilers do is
- // making the struct 1-byte sized.
+ // C++ requires every struct to be addressable, so what C++ compilers do
+ // is making the struct 1-byte sized.
+ //
+ // This is apparently not the case for C, see:
+ // https://github.com/servo/rust-bindgen/issues/551
+ //
+ // Just get the layout, and assume C++ if not.
//
// NOTE: This check is conveniently here to avoid the dummy fields we
// may add for unused template parameters.
if self.is_unsized(ctx) {
- let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
- let field = StructFieldBuilder::named("_address")
- .pub_()
- .build_ty(ty);
- fields.push(field);
+ let has_address = layout.map_or(true, |l| l.size != 0);
+ if has_address {
+ let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
+ let field = StructFieldBuilder::named("_address")
+ .pub_()
+ .build_ty(ty);
+ fields.push(field);
+ }
}
let mut generics = aster::AstBuilder::new().generics();
diff --git a/tests/expectations/tests/c-empty-layout.rs b/tests/expectations/tests/c-empty-layout.rs
new file mode 100644
index 00000000..7dc16d48
--- /dev/null
+++ b/tests/expectations/tests/c-empty-layout.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+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 ) ));
+}
+impl Clone for Foo {
+ fn clone(&self) -> Self { *self }
+}
diff --git a/tests/expectations/tests/cpp-empty-layout.rs b/tests/expectations/tests/cpp-empty-layout.rs
new file mode 100644
index 00000000..fbeb3d5e
--- /dev/null
+++ b/tests/expectations/tests/cpp-empty-layout.rs
@@ -0,0 +1,21 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct Foo {
+ pub _address: u8,
+}
+#[test]
+fn bindgen_test_layout_Foo() {
+ assert_eq!(::std::mem::size_of::<Foo>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( Foo ) ));
+ assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! (
+ "Alignment of " , stringify ! ( Foo ) ));
+}
+impl Clone for Foo {
+ fn clone(&self) -> Self { *self }
+}
diff --git a/tests/headers/c-empty-layout.h b/tests/headers/c-empty-layout.h
new file mode 100644
index 00000000..1fe02e89
--- /dev/null
+++ b/tests/headers/c-empty-layout.h
@@ -0,0 +1 @@
+struct Foo {};
diff --git a/tests/headers/cpp-empty-layout.hpp b/tests/headers/cpp-empty-layout.hpp
new file mode 100644
index 00000000..1fe02e89
--- /dev/null
+++ b/tests/headers/cpp-empty-layout.hpp
@@ -0,0 +1 @@
+struct Foo {};