Skip to content

Commit

Permalink
Fix handling of anonymous names in Clang 16.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pcwalton committed Oct 21, 2022
1 parent 61ced32 commit 96c5b25
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
5 changes: 4 additions & 1 deletion bindgen/ir/comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
use crate::clang;
use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2};
use crate::ir::derive::CanDeriveCopy;
use crate::ir::item;
use crate::parse::{ClangItemParser, ParseError};
use crate::HashMap;
use crate::NonCopyUnionStyle;
Expand Down Expand Up @@ -1422,7 +1423,9 @@ impl CompInfo {

// A declaration of an union or a struct without name
// could also be an unnamed field, unfortunately.
if cur.spelling().is_empty() &&
let mut spelling = cur.spelling();
item::normalize_name_for_clang_16(&mut spelling);
if spelling.is_empty() &&
cur.kind() != CXCursor_EnumDecl
{
let ty = cur.cur_type();
Expand Down
13 changes: 13 additions & 0 deletions bindgen/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2016,3 +2016,16 @@ impl<'a> NameOptions<'a> {
self.item.real_canonical_name(self.ctx, self)
}
}

/// Normalizes names so that we can handle them identically in Clang 16 and earlier versions.
///
/// In Clang 16, anonymous names have names like `(anonymous union at foo.c:16)`, whereas in earlier
/// versions of Clang they were the empty string. This function normalizes all such names to the
/// empty string so that we can handle them identically.
pub fn normalize_name_for_clang_16(name: &mut String) {
// This may seem fragile, but ")" is not a valid character in C identifiers, so it should
// actually be a reasonably robust check.
if name.ends_with(")") {
name.truncate(0);
}
}
5 changes: 5 additions & 0 deletions bindgen/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use super::template::{
};
use super::traversal::{EdgeKind, Trace, Tracer};
use crate::clang::{self, Cursor};
use crate::ir::item;
use crate::parse::{ClangItemParser, ParseError, ParseResult};
use std::borrow::Cow;
use std::io;
Expand Down Expand Up @@ -1112,6 +1113,8 @@ impl Type {
}
}

item::normalize_name_for_clang_16(&mut name);

TypeKind::Enum(enum_)
}
CXType_Record => {
Expand All @@ -1132,6 +1135,8 @@ impl Type {
}
}

item::normalize_name_for_clang_16(&mut name);

TypeKind::Comp(complex)
}
CXType_Vector => {
Expand Down

0 comments on commit 96c5b25

Please sign in to comment.