Skip to content

Commit 96c5b25

Browse files
committed
Fix handling of anonymous names in Clang 16.
In trunk, Clang started emitting names like `"(unnamed enum at foo.cpp:4:2)"` for unnamed enums, structs, and unions, while previous versions emitted the empty string. This caused panics. This commit simply rewrites such names back to the empty string so that we stay compatible with both old and new versions of Clang. Closes rust-lang#2312.
1 parent 61ced32 commit 96c5b25

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

bindgen/ir/comp.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
1212
use crate::clang;
1313
use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2};
1414
use crate::ir::derive::CanDeriveCopy;
15+
use crate::ir::item;
1516
use crate::parse::{ClangItemParser, ParseError};
1617
use crate::HashMap;
1718
use crate::NonCopyUnionStyle;
@@ -1422,7 +1423,9 @@ impl CompInfo {
14221423

14231424
// A declaration of an union or a struct without name
14241425
// could also be an unnamed field, unfortunately.
1425-
if cur.spelling().is_empty() &&
1426+
let mut spelling = cur.spelling();
1427+
item::normalize_name_for_clang_16(&mut spelling);
1428+
if spelling.is_empty() &&
14261429
cur.kind() != CXCursor_EnumDecl
14271430
{
14281431
let ty = cur.cur_type();

bindgen/ir/item.rs

+13
Original file line numberDiff line numberDiff line change
@@ -2016,3 +2016,16 @@ impl<'a> NameOptions<'a> {
20162016
self.item.real_canonical_name(self.ctx, self)
20172017
}
20182018
}
2019+
2020+
/// Normalizes names so that we can handle them identically in Clang 16 and earlier versions.
2021+
///
2022+
/// In Clang 16, anonymous names have names like `(anonymous union at foo.c:16)`, whereas in earlier
2023+
/// versions of Clang they were the empty string. This function normalizes all such names to the
2024+
/// empty string so that we can handle them identically.
2025+
pub fn normalize_name_for_clang_16(name: &mut String) {
2026+
// This may seem fragile, but ")" is not a valid character in C identifiers, so it should
2027+
// actually be a reasonably robust check.
2028+
if name.ends_with(")") {
2029+
name.truncate(0);
2030+
}
2031+
}

bindgen/ir/ty.rs

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use super::template::{
1414
};
1515
use super::traversal::{EdgeKind, Trace, Tracer};
1616
use crate::clang::{self, Cursor};
17+
use crate::ir::item;
1718
use crate::parse::{ClangItemParser, ParseError, ParseResult};
1819
use std::borrow::Cow;
1920
use std::io;
@@ -1112,6 +1113,8 @@ impl Type {
11121113
}
11131114
}
11141115

1116+
item::normalize_name_for_clang_16(&mut name);
1117+
11151118
TypeKind::Enum(enum_)
11161119
}
11171120
CXType_Record => {
@@ -1132,6 +1135,8 @@ impl Type {
11321135
}
11331136
}
11341137

1138+
item::normalize_name_for_clang_16(&mut name);
1139+
11351140
TypeKind::Comp(complex)
11361141
}
11371142
CXType_Vector => {

0 commit comments

Comments
 (0)