Skip to content

Commit 8eb9e3f

Browse files
committed
Forward declared structs now generate opaque enums
1 parent ab6117c commit 8eb9e3f

File tree

4 files changed

+40
-9
lines changed

4 files changed

+40
-9
lines changed

src/clang.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ impl Cursor {
190190
unsafe { clang_getCursorKind(self.x) }
191191
}
192192

193+
/// Returns true is the cursor is a definition
194+
pub fn is_definition(&self) -> bool {
195+
unsafe { clang_isCursorDefinition(self.x) != 0 }
196+
}
197+
193198
/// Is the referent an anonymous record definition?
194199
pub fn is_anonymous(&self) -> bool {
195200
unsafe { clang_Cursor_isAnonymous(self.x) != 0 }

src/codegen/mod.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,22 @@ impl CodeGenerator for CompInfo {
748748
return;
749749
}
750750

751+
let applicable_template_args = item.applicable_template_args(ctx);
752+
753+
// generate tuple struct if struct or union is a forward declaration,
754+
// skip for now if template parameters are needed.
755+
if self.is_forward_declaration() && applicable_template_args.is_empty(){
756+
let struct_name = item.canonical_name(ctx);
757+
let struct_name = ctx.rust_ident_raw(&struct_name);
758+
let tuple_struct = quote_item!(ctx.ext_cx(),
759+
#[repr(C)]
760+
pub struct $struct_name([u8; 0]);
761+
)
762+
.unwrap();
763+
result.push(tuple_struct);
764+
return;
765+
}
766+
751767
if self.is_template_specialization() {
752768
let layout = item.kind().expect_type().layout(ctx);
753769

@@ -775,8 +791,6 @@ impl CodeGenerator for CompInfo {
775791
return;
776792
}
777793

778-
let applicable_template_args = item.applicable_template_args(ctx);
779-
780794
let mut attributes = vec![];
781795
let mut needs_clone_impl = false;
782796
if let Some(comment) = item.comment() {

src/ir/comp.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ pub struct CompInfo {
290290
/// Used to detect if we've run in a has_destructor cycle while cycling
291291
/// around the template arguments.
292292
detect_has_destructor_cycle: Cell<bool>,
293+
294+
/// Used to indicate when a struct has been forward declared. Usually used
295+
/// in headers so that APIs can't modify them directly.
296+
is_forward_declaration: bool,
293297
}
294298

295299
impl CompInfo {
@@ -314,6 +318,7 @@ impl CompInfo {
314318
found_unknown_attr: false,
315319
detect_derive_debug_cycle: Cell::new(false),
316320
detect_has_destructor_cycle: Cell::new(false),
321+
is_forward_declaration: false,
317322
}
318323
}
319324

@@ -481,6 +486,14 @@ impl CompInfo {
481486
debug!("CompInfo::from_ty({:?}, {:?})", kind, cursor);
482487

483488
let mut ci = CompInfo::new(kind);
489+
ci.is_forward_declaration = location.map_or(true, |cur| {
490+
match cur.kind() {
491+
CXCursor_StructDecl |
492+
CXCursor_UnionDecl |
493+
CXCursor_ClassDecl => !cur.is_definition(),
494+
_ => false,
495+
}
496+
});
484497
ci.is_anonymous = cursor.is_anonymous();
485498
ci.template_args = match ty.template_args() {
486499
// In forward declarations and not specializations,
@@ -822,6 +835,11 @@ impl CompInfo {
822835
.map_or(false, |ci| ci.has_vtable(ctx))
823836
})
824837
}
838+
839+
/// Returns true if compound type has been forward declared
840+
pub fn is_forward_declaration(&self) -> bool {
841+
self.is_forward_declaration
842+
}
825843
}
826844

827845
impl CanDeriveDebug for CompInfo {

tests/expectations/tests/same_struct_name_in_different_namespaces.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@
55

66

77
#[repr(C)]
8-
#[derive(Debug, Copy)]
9-
pub struct JS_Zone {
10-
pub _address: u8,
11-
}
12-
impl Clone for JS_Zone {
13-
fn clone(&self) -> Self { *self }
14-
}
8+
pub struct JS_Zone([u8; 0]);
159
#[repr(C)]
1610
#[derive(Debug, Copy)]
1711
pub struct JS_shadow_Zone {

0 commit comments

Comments
 (0)