diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-01-26 05:11:53 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-26 05:11:53 -0800 |
commit | 5cc25067b27af15ba67be645235f9c90573d6313 (patch) | |
tree | f6d1661beefd466b1861240e5c88d195e7de96de | |
parent | e4420b601031c4ec8d84fe8340961447e3a2c87a (diff) | |
parent | 78aaa32037880c28cce640aa8f989f738280f164 (diff) |
Auto merge of #370 - cynicaldevil:detect-forward, r=emilio
Forward declared structs now generate opaque enums
@emilio : I checked the test outputs again, and it seems that these changes are affecting struct *definitions* as well. Hence, I have not committed the test changes yet.
Fixes #62
-rw-r--r-- | src/clang.rs | 5 | ||||
-rw-r--r-- | src/codegen/mod.rs | 18 | ||||
-rw-r--r-- | src/ir/comp.rs | 18 | ||||
-rw-r--r-- | tests/expectations/tests/forward_declared_complex_types.rs | 50 | ||||
-rw-r--r-- | tests/expectations/tests/same_struct_name_in_different_namespaces.rs | 8 | ||||
-rw-r--r-- | tests/headers/forward_declared_complex_types.hpp | 16 |
6 files changed, 106 insertions, 9 deletions
diff --git a/src/clang.rs b/src/clang.rs index 491aaa07..9cf51436 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -190,6 +190,11 @@ impl Cursor { unsafe { clang_getCursorKind(self.x) } } + /// Returns true is the cursor is a definition + pub fn is_definition(&self) -> bool { + unsafe { clang_isCursorDefinition(self.x) != 0 } + } + /// Is the referent an anonymous record definition? pub fn is_anonymous(&self) -> bool { unsafe { clang_Cursor_isAnonymous(self.x) != 0 } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 0991391a..c92e95fa 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -763,6 +763,22 @@ impl CodeGenerator for CompInfo { return; } + let applicable_template_args = item.applicable_template_args(ctx); + + // generate tuple struct if struct or union is a forward declaration, + // skip for now if template parameters are needed. + if self.is_forward_declaration() && applicable_template_args.is_empty(){ + let struct_name = item.canonical_name(ctx); + let struct_name = ctx.rust_ident_raw(&struct_name); + let tuple_struct = quote_item!(ctx.ext_cx(), + #[repr(C)] + pub struct $struct_name([u8; 0]); + ) + .unwrap(); + result.push(tuple_struct); + return; + } + if self.is_template_specialization() { let layout = item.kind().expect_type().layout(ctx); @@ -790,8 +806,6 @@ impl CodeGenerator for CompInfo { return; } - let applicable_template_args = item.applicable_template_args(ctx); - let mut attributes = vec![]; let mut needs_clone_impl = false; if let Some(comment) = item.comment() { diff --git a/src/ir/comp.rs b/src/ir/comp.rs index ac68b672..4eea1d7a 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -290,6 +290,10 @@ pub struct CompInfo { /// Used to detect if we've run in a has_destructor cycle while cycling /// around the template arguments. detect_has_destructor_cycle: Cell<bool>, + + /// Used to indicate when a struct has been forward declared. Usually used + /// in headers so that APIs can't modify them directly. + is_forward_declaration: bool, } impl CompInfo { @@ -314,6 +318,7 @@ impl CompInfo { found_unknown_attr: false, detect_derive_debug_cycle: Cell::new(false), detect_has_destructor_cycle: Cell::new(false), + is_forward_declaration: false, } } @@ -481,6 +486,14 @@ impl CompInfo { debug!("CompInfo::from_ty({:?}, {:?})", kind, cursor); let mut ci = CompInfo::new(kind); + ci.is_forward_declaration = location.map_or(true, |cur| { + match cur.kind() { + CXCursor_StructDecl | + CXCursor_UnionDecl | + CXCursor_ClassDecl => !cur.is_definition(), + _ => false, + } + }); ci.is_anonymous = cursor.is_anonymous(); ci.template_args = match ty.template_args() { // In forward declarations and not specializations, @@ -822,6 +835,11 @@ impl CompInfo { .map_or(false, |ci| ci.has_vtable(ctx)) }) } + + /// Returns true if compound type has been forward declared + pub fn is_forward_declaration(&self) -> bool { + self.is_forward_declaration + } } impl CanDeriveDebug for CompInfo { diff --git a/tests/expectations/tests/forward_declared_complex_types.rs b/tests/expectations/tests/forward_declared_complex_types.rs new file mode 100644 index 00000000..77849a91 --- /dev/null +++ b/tests/expectations/tests/forward_declared_complex_types.rs @@ -0,0 +1,50 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Foo_empty { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_Foo_empty() { + assert_eq!(::std::mem::size_of::<Foo_empty>() , 1usize); + assert_eq!(::std::mem::align_of::<Foo_empty>() , 1usize); +} +impl Clone for Foo_empty { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +pub struct Foo([u8; 0]); +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Bar { + pub f: *mut Foo, +} +#[test] +fn bindgen_test_layout_Bar() { + assert_eq!(::std::mem::size_of::<Bar>() , 8usize); + assert_eq!(::std::mem::align_of::<Bar>() , 8usize); +} +impl Clone for Bar { + fn clone(&self) -> Self { *self } +} +extern "C" { + #[link_name = "_Z10baz_structP3Foo"] + pub fn baz_struct(f: *mut Foo); +} +#[repr(C)] +pub struct Union([u8; 0]); +extern "C" { + #[link_name = "_Z9baz_unionP5Union"] + pub fn baz_union(u: *mut Union); +} +#[repr(C)] +pub struct Quux([u8; 0]); +extern "C" { + #[link_name = "_Z9baz_classP4Quux"] + pub fn baz_class(q: *mut Quux); +} diff --git a/tests/expectations/tests/same_struct_name_in_different_namespaces.rs b/tests/expectations/tests/same_struct_name_in_different_namespaces.rs index 8e7c177b..c59e4d44 100644 --- a/tests/expectations/tests/same_struct_name_in_different_namespaces.rs +++ b/tests/expectations/tests/same_struct_name_in_different_namespaces.rs @@ -5,13 +5,7 @@ #[repr(C)] -#[derive(Debug, Copy)] -pub struct JS_Zone { - pub _address: u8, -} -impl Clone for JS_Zone { - fn clone(&self) -> Self { *self } -} +pub struct JS_Zone([u8; 0]); #[repr(C)] #[derive(Debug, Copy)] pub struct JS_shadow_Zone { diff --git a/tests/headers/forward_declared_complex_types.hpp b/tests/headers/forward_declared_complex_types.hpp new file mode 100644 index 00000000..ffc779ad --- /dev/null +++ b/tests/headers/forward_declared_complex_types.hpp @@ -0,0 +1,16 @@ +struct Foo_empty {}; +struct Foo; + +struct Bar { + Foo *f; +}; + +void baz_struct(Foo* f); + +union Union; + +void baz_union(Union* u); + +class Quux; + +void baz_class(Quux* q); |