summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhil Shagrithaya <nikhilshagri@gmail.com>2016-12-29 18:26:25 +0530
committerNikhil Shagrithaya <nikhilshagri@gmail.com>2017-01-26 18:27:48 +0530
commit8eb9e3f406f83f297ccacf687791948cfd4ba872 (patch)
treedd298005f875781145b7210ed4d964c84857b3ff
parentab6117c6b486cfcbf65adf8702dbc8472b4eb8c0 (diff)
Forward declared structs now generate opaque enums
-rw-r--r--src/clang.rs5
-rw-r--r--src/codegen/mod.rs18
-rw-r--r--src/ir/comp.rs18
-rw-r--r--tests/expectations/tests/same_struct_name_in_different_namespaces.rs8
4 files changed, 40 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 7451dd11..0cc5a637 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -748,6 +748,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);
@@ -775,8 +791,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 968bf879..ada6c064 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/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 {