Skip to content

Commit c5cda6a

Browse files
emiliopcwalton
authored andcommitted
clang: Detect anonymous items explicitly, rather than relying on empty names.
In Clang 16, anonymous items may return names like `(anonymous union at ..)` rather than empty names. The right way to detect them is using clang_Cursor_isAnonymous. Fixes rust-lang#2312 Closes rust-lang#2316 Co-Authored-by: Patrick Walton <[email protected]>
1 parent 9ca5f85 commit c5cda6a

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

src/clang.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ impl Cursor {
5252
unsafe { clang_isDeclaration(self.kind()) != 0 }
5353
}
5454

55+
/// Is this cursor's referent an anonymous record or so?
56+
pub fn is_anonymous(&self) -> bool {
57+
unsafe { clang_Cursor_isAnonymous(self.x) != 0 }
58+
}
59+
5560
/// Get this cursor's referent's spelling.
5661
pub fn spelling(&self) -> String {
5762
unsafe { cxstring_into_string(clang_getCursorSpelling(self.x)) }

src/ir/comp.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,8 +1403,7 @@ impl CompInfo {
14031403

14041404
// A declaration of an union or a struct without name
14051405
// could also be an unnamed field, unfortunately.
1406-
if cur.spelling().is_empty() &&
1407-
cur.kind() != CXCursor_EnumDecl
1406+
if cur.is_anonymous() && cur.kind() != CXCursor_EnumDecl
14081407
{
14091408
let ty = cur.cur_type();
14101409
let public = cur.public_accessible();

src/ir/ty.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,12 @@ impl Type {
698698

699699
let layout = ty.fallible_layout(ctx).ok();
700700
let cursor = ty.declaration();
701-
let mut name = cursor.spelling();
701+
let is_anonymous = cursor.is_anonymous();
702+
let mut name = if is_anonymous {
703+
None
704+
} else {
705+
Some(cursor.spelling()).filter(|n| !n.is_empty())
706+
};
702707

703708
debug!(
704709
"from_clang_ty: {:?}, ty: {:?}, loc: {:?}",
@@ -732,7 +737,7 @@ impl Type {
732737
if is_canonical_objcpointer && is_template_type_param {
733738
// Objective-C generics are just ids with fancy name.
734739
// To keep it simple, just name them ids
735-
name = "id".to_owned();
740+
name = Some("id".to_owned());
736741
}
737742
}
738743

@@ -861,7 +866,7 @@ impl Type {
861866
return Err(ParseError::Recurse);
862867
}
863868
} else {
864-
name = location.spelling();
869+
name = Some(location.spelling());
865870
}
866871

867872
let complex = CompInfo::from_ty(
@@ -903,7 +908,7 @@ impl Type {
903908
CXType_Typedef
904909
);
905910

906-
name = current.spelling();
911+
name = Some(location.spelling());
907912

908913
let inner_ty = cur
909914
.typedef_type()
@@ -1096,10 +1101,10 @@ impl Type {
10961101
CXType_Enum => {
10971102
let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?");
10981103

1099-
if name.is_empty() {
1104+
if !is_anonymous {
11001105
let pretty_name = ty.spelling();
11011106
if clang::is_valid_identifier(&pretty_name) {
1102-
name = pretty_name;
1107+
name = Some(pretty_name);
11031108
}
11041109
}
11051110

@@ -1114,12 +1119,12 @@ impl Type {
11141119
)
11151120
.expect("Not a complex type?");
11161121

1117-
if name.is_empty() {
1122+
if !is_anonymous {
11181123
// The pretty-printed name may contain typedefed name,
11191124
// but may also be "struct (anonymous at .h:1)"
11201125
let pretty_name = ty.spelling();
11211126
if clang::is_valid_identifier(&pretty_name) {
1122-
name = pretty_name;
1127+
name = Some(pretty_name);
11231128
}
11241129
}
11251130

@@ -1159,7 +1164,9 @@ impl Type {
11591164
CXType_ObjCClass | CXType_ObjCInterface => {
11601165
let interface = ObjCInterface::from_ty(&location, ctx)
11611166
.expect("Not a valid objc interface?");
1162-
name = interface.rust_name();
1167+
if !is_anonymous {
1168+
name = Some(interface.rust_name());
1169+
}
11631170
TypeKind::ObjCInterface(interface)
11641171
}
11651172
CXType_Dependent => {
@@ -1177,7 +1184,7 @@ impl Type {
11771184
}
11781185
};
11791186

1180-
let name = if name.is_empty() { None } else { Some(name) };
1187+
name = name.filter(|n| !n.is_empty());
11811188

11821189
let is_const = ty.is_const() ||
11831190
(ty.kind() == CXType_ConstantArray &&

0 commit comments

Comments
 (0)