Skip to content

Commit be53402

Browse files
emiliopcwalton
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 #2312 Closes #2316 Co-Authored-by: Patrick Walton <[email protected]>
1 parent 0142c0a commit be53402

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

bindgen/clang.rs

+5
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ impl Cursor {
8686
unsafe { clang_isDeclaration(self.kind()) != 0 }
8787
}
8888

89+
/// Is this cursor's referent an anonymous record or so?
90+
pub fn is_anonymous(&self) -> bool {
91+
unsafe { clang_Cursor_isAnonymous(self.x) != 0 }
92+
}
93+
8994
/// Get this cursor's referent's spelling.
9095
pub fn spelling(&self) -> String {
9196
unsafe { cxstring_into_string(clang_getCursorSpelling(self.x)) }

bindgen/ir/comp.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ impl CompInfo {
14221422

14231423
// A declaration of an union or a struct without name
14241424
// could also be an unnamed field, unfortunately.
1425-
if cur.spelling().is_empty() &&
1425+
if cur.is_anonymous() &&
14261426
cur.kind() != CXCursor_EnumDecl
14271427
{
14281428
let ty = cur.cur_type();

bindgen/ir/ty.rs

+17-10
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()
@@ -1105,10 +1110,10 @@ impl Type {
11051110
CXType_Enum => {
11061111
let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?");
11071112

1108-
if name.is_empty() {
1113+
if !is_anonymous {
11091114
let pretty_name = ty.spelling();
11101115
if clang::is_valid_identifier(&pretty_name) {
1111-
name = pretty_name;
1116+
name = Some(pretty_name);
11121117
}
11131118
}
11141119

@@ -1123,12 +1128,12 @@ impl Type {
11231128
)
11241129
.expect("Not a complex type?");
11251130

1126-
if name.is_empty() {
1131+
if !is_anonymous {
11271132
// The pretty-printed name may contain typedefed name,
11281133
// but may also be "struct (anonymous at .h:1)"
11291134
let pretty_name = ty.spelling();
11301135
if clang::is_valid_identifier(&pretty_name) {
1131-
name = pretty_name;
1136+
name = Some(pretty_name);
11321137
}
11331138
}
11341139

@@ -1168,7 +1173,9 @@ impl Type {
11681173
CXType_ObjCClass | CXType_ObjCInterface => {
11691174
let interface = ObjCInterface::from_ty(&location, ctx)
11701175
.expect("Not a valid objc interface?");
1171-
name = interface.rust_name();
1176+
if !is_anonymous {
1177+
name = Some(interface.rust_name());
1178+
}
11721179
TypeKind::ObjCInterface(interface)
11731180
}
11741181
CXType_Dependent => {
@@ -1186,7 +1193,7 @@ impl Type {
11861193
}
11871194
};
11881195

1189-
let name = if name.is_empty() { None } else { Some(name) };
1196+
name = name.filter(|n| !n.is_empty());
11901197

11911198
let is_const = ty.is_const() ||
11921199
(ty.kind() == CXType_ConstantArray &&

0 commit comments

Comments
 (0)