Skip to content

Commit bf0bbda

Browse files
author
bors-servo
authored
Auto merge of #532 - emilio:random-bugfixes, r=fitzgen
Add a workaround for #528, and fix #527 r? @fitzgen
2 parents 051b16a + ea39b98 commit bf0bbda

File tree

8 files changed

+152
-4
lines changed

8 files changed

+152
-4
lines changed

src/clang.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,13 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
15021502
&specialized);
15031503
}
15041504
}
1505+
1506+
if let Some(parent) = c.fallible_semantic_parent() {
1507+
println!("");
1508+
print_cursor(depth,
1509+
String::from(prefix) + "semantic-parent.",
1510+
&parent);
1511+
}
15051512
}
15061513

15071514
fn print_type<S: AsRef<str>>(depth: isize, prefix: S, ty: &Type) {

src/ir/comp.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,19 @@ impl CompInfo {
625625
// StructDecl to note incomplete structs that hasn't been
626626
// forward-declared before, see:
627627
//
628+
// Also, clang seems to scope struct definitions inside
629+
// unions to the whole translation unit. Since those are
630+
// anonymous, let's just assume that if the cursor we've
631+
// found is a definition it's a valid inner type.
632+
//
633+
// Note that doing this could be always ok, but let's just
634+
// keep the union check for now.
635+
//
628636
// https://github.com/servo/rust-bindgen/issues/482
629-
if cur.semantic_parent() != cursor {
637+
let is_inner_struct = cur.semantic_parent() == cursor ||
638+
(kind == CompKind::Union &&
639+
cur.is_definition());
640+
if !is_inner_struct {
630641
return CXChildVisit_Continue;
631642
}
632643

src/ir/function.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,13 @@ fn get_abi(cc: CXCallingConv) -> Option<abi::Abi> {
105105
}
106106

107107
/// Get the mangled name for the cursor's referent.
108-
pub fn cursor_mangling(cursor: &clang::Cursor) -> Option<String> {
108+
pub fn cursor_mangling(ctx: &BindgenContext,
109+
cursor: &clang::Cursor)
110+
-> Option<String> {
111+
if !ctx.options().enable_mangling {
112+
return None;
113+
}
114+
109115
// We early return here because libclang may crash in some case
110116
// if we pass in a variable inside a partial specialized template.
111117
// See servo/rust-bindgen#67, and servo/rust-bindgen#462.
@@ -318,7 +324,7 @@ impl ClangSubItemParser for Function {
318324
let name = cursor.spelling();
319325
assert!(!name.is_empty(), "Empty function name?");
320326

321-
let mut mangled_name = cursor_mangling(&cursor);
327+
let mut mangled_name = cursor_mangling(context, &cursor);
322328
if mangled_name.as_ref() == Some(&name) {
323329
mangled_name = None;
324330
}

src/ir/var.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ impl ClangSubItemParser for Var {
256256
.map(VarType::String)
257257
};
258258

259-
let mangling = cursor_mangling(&cursor);
259+
let mangling = cursor_mangling(ctx, &cursor);
260260
let var = Var::new(name, mangling, ty, value, is_const);
261261

262262
Ok(ParseResult::New(var, Some(cursor)))

src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,18 @@ impl Builder {
212212
self
213213
}
214214

215+
/// Whether to use the clang-provided name mangling. This is true and
216+
/// probably needed for C++ features.
217+
///
218+
/// However, some old libclang versions seem to return incorrect results in
219+
/// some cases for non-mangled functions, see [1], so we allow disabling it.
220+
///
221+
/// [1]: https://github.com/servo/rust-bindgen/issues/528
222+
pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
223+
self.options.enable_mangling = doit;
224+
self
225+
}
226+
215227
/// Generate a C/C++ file that includes the header and has dummy uses of
216228
/// every type defined in the header.
217229
pub fn dummy_uses<T: Into<String>>(mut self, dummy_uses: T) -> Builder {
@@ -572,6 +584,15 @@ pub struct BindgenOptions {
572584
/// Intead of emitting 'use objc;' to files generated from objective c files,
573585
/// generate '#[macro_use] extern crate objc;'
574586
pub objc_extern_crate: bool,
587+
588+
/// Whether to use the clang-provided name mangling. This is true and
589+
/// probably needed for C++ features.
590+
///
591+
/// However, some old libclang versions seem to return incorrect results in
592+
/// some cases for non-mangled functions, see [1], so we allow disabling it.
593+
///
594+
/// [1]: https://github.com/servo/rust-bindgen/issues/528
595+
pub enable_mangling: bool,
575596
}
576597

577598
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -626,6 +647,7 @@ impl Default for BindgenOptions {
626647
generate_comments: true,
627648
whitelist_recursively: true,
628649
objc_extern_crate: false,
650+
enable_mangling: true,
629651
}
630652
}
631653
}

src/options.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pub fn builder_from_flags<I>
6060
Arg::with_name("objc-extern-crate")
6161
.long("objc-extern-crate")
6262
.help("Use extern crate instead of use for objc"),
63+
Arg::with_name("distrust-clang-mangling")
64+
.long("distrust-clang-mangling")
65+
.help("Do not trust the libclang-provided mangling"),
6366
Arg::with_name("builtins")
6467
.long("builtins")
6568
.help("Output bindings for builtin definitions, e.g. \
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
9+
impl <T> __BindgenUnionField<T> {
10+
#[inline]
11+
pub fn new() -> Self { __BindgenUnionField(::std::marker::PhantomData) }
12+
#[inline]
13+
pub unsafe fn as_ref(&self) -> &T { ::std::mem::transmute(self) }
14+
#[inline]
15+
pub unsafe fn as_mut(&mut self) -> &mut T { ::std::mem::transmute(self) }
16+
}
17+
impl <T> ::std::default::Default for __BindgenUnionField<T> {
18+
#[inline]
19+
fn default() -> Self { Self::new() }
20+
}
21+
impl <T> ::std::clone::Clone for __BindgenUnionField<T> {
22+
#[inline]
23+
fn clone(&self) -> Self { Self::new() }
24+
}
25+
impl <T> ::std::marker::Copy for __BindgenUnionField<T> { }
26+
impl <T> ::std::fmt::Debug for __BindgenUnionField<T> {
27+
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
28+
fmt.write_str("__BindgenUnionField")
29+
}
30+
}
31+
#[repr(C)]
32+
#[derive(Debug, Default, Copy)]
33+
pub struct s {
34+
pub u: s__bindgen_ty_1,
35+
}
36+
#[repr(C)]
37+
#[derive(Debug, Default, Copy)]
38+
pub struct s__bindgen_ty_1 {
39+
pub field: __BindgenUnionField<s__bindgen_ty_1_inner>,
40+
pub bindgen_union_field: u32,
41+
}
42+
#[repr(C)]
43+
#[derive(Debug, Default, Copy)]
44+
pub struct s__bindgen_ty_1_inner {
45+
pub b: ::std::os::raw::c_int,
46+
}
47+
#[test]
48+
fn bindgen_test_layout_s__bindgen_ty_1_inner() {
49+
assert_eq!(::std::mem::size_of::<s__bindgen_ty_1_inner>() , 4usize ,
50+
concat ! ( "Size of: " , stringify ! ( s__bindgen_ty_1_inner )
51+
));
52+
assert_eq! (::std::mem::align_of::<s__bindgen_ty_1_inner>() , 4usize ,
53+
concat ! (
54+
"Alignment of " , stringify ! ( s__bindgen_ty_1_inner ) ));
55+
assert_eq! (unsafe {
56+
& ( * ( 0 as * const s__bindgen_ty_1_inner ) ) . b as * const
57+
_ as usize } , 0usize , concat ! (
58+
"Alignment of field: " , stringify ! ( s__bindgen_ty_1_inner )
59+
, "::" , stringify ! ( b ) ));
60+
}
61+
impl Clone for s__bindgen_ty_1_inner {
62+
fn clone(&self) -> Self { *self }
63+
}
64+
#[test]
65+
fn bindgen_test_layout_s__bindgen_ty_1() {
66+
assert_eq!(::std::mem::size_of::<s__bindgen_ty_1>() , 4usize , concat ! (
67+
"Size of: " , stringify ! ( s__bindgen_ty_1 ) ));
68+
assert_eq! (::std::mem::align_of::<s__bindgen_ty_1>() , 4usize , concat !
69+
( "Alignment of " , stringify ! ( s__bindgen_ty_1 ) ));
70+
assert_eq! (unsafe {
71+
& ( * ( 0 as * const s__bindgen_ty_1 ) ) . field as * const _
72+
as usize } , 0usize , concat ! (
73+
"Alignment of field: " , stringify ! ( s__bindgen_ty_1 ) ,
74+
"::" , stringify ! ( field ) ));
75+
}
76+
impl Clone for s__bindgen_ty_1 {
77+
fn clone(&self) -> Self { *self }
78+
}
79+
#[test]
80+
fn bindgen_test_layout_s() {
81+
assert_eq!(::std::mem::size_of::<s>() , 4usize , concat ! (
82+
"Size of: " , stringify ! ( s ) ));
83+
assert_eq! (::std::mem::align_of::<s>() , 4usize , concat ! (
84+
"Alignment of " , stringify ! ( s ) ));
85+
assert_eq! (unsafe { & ( * ( 0 as * const s ) ) . u as * const _ as usize
86+
} , 0usize , concat ! (
87+
"Alignment of field: " , stringify ! ( s ) , "::" , stringify
88+
! ( u ) ));
89+
}
90+
impl Clone for s {
91+
fn clone(&self) -> Self { *self }
92+
}

tests/headers/anon_struct_in_union.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
struct s {
2+
union {
3+
struct inner {
4+
int b;
5+
} field;
6+
} u;
7+
};

0 commit comments

Comments
 (0)