Skip to content

Commit c4ade05

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

File tree

4 files changed

+33
-10
lines changed

4 files changed

+33
-10
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: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,20 @@ impl CodeGenerator for CompInfo {
748748
return;
749749
}
750750

751+
let applicable_template_args = item.applicable_template_args(ctx);
752+
753+
// generate an opaque enum 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 name = item.canonical_name(ctx);
757+
let builder = EnumBuilder::new(
758+
aster::AstBuilder::new().item().pub_(),
759+
&name, "name", true);
760+
let enum_ = builder.build(ctx, item.to_rust_ty(ctx), result);
761+
result.push(enum_);
762+
return;
763+
}
764+
751765
if self.is_template_specialization() {
752766
let layout = item.kind().expect_type().layout(ctx);
753767

@@ -775,8 +789,6 @@ impl CodeGenerator for CompInfo {
775789
return;
776790
}
777791

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

src/ir/comp.rs

Lines changed: 13 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,9 @@ 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+
(cur.kind() == CXCursor_StructDecl || cur.kind() == CXCursor_UnionDecl) &&
491+
!cur.is_definition());
484492
ci.is_anonymous = cursor.is_anonymous();
485493
ci.template_args = match ty.template_args() {
486494
// In forward declarations and not specializations,
@@ -822,6 +830,11 @@ impl CompInfo {
822830
.map_or(false, |ci| ci.has_vtable(ctx))
823831
})
824832
}
833+
834+
/// Returns true if compound type has been forward declared
835+
pub fn is_forward_declaration(&self) -> bool {
836+
self.is_forward_declaration
837+
}
825838
}
826839

827840
impl CanDeriveDebug for CompInfo {

tests/expectations/tests/same_struct_name_in_different_namespaces.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,7 @@
44
#![allow(non_snake_case)]
55

66

7-
#[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-
}
7+
pub enum JS_Zone { }
158
#[repr(C)]
169
#[derive(Debug, Copy)]
1710
pub struct JS_shadow_Zone {

0 commit comments

Comments
 (0)