Skip to content

Commit

Permalink
Improve workaround for LLVM bug when evaluating value-dependent expre…
Browse files Browse the repository at this point in the history
…ssions.

Using the canonical type makes it work across typedefs.

Fixes #1590
  • Loading branch information
emilio committed Jul 9, 2019
1 parent d789817 commit 6f92b1c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
36 changes: 17 additions & 19 deletions src/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1875,27 +1875,25 @@ impl EvalResult {
return None;
}

// Clang has an internal assertion we can trigger if we try to evaluate
// a cursor containing a variadic template type reference. Triggering
// the assertion aborts the process, and we don't want that. Clang
// *also* doesn't expose any API for finding variadic vs non-variadic
// template type references, let alone whether a type referenced is a
// template type, instead they seem to show up as type references to an
// unexposed type. Our solution is to just flat out ban all
// `CXType_Unexposed` from evaluation.
let mut found_cant_eval = false;
cursor.visit(|c| if c.kind() == CXCursor_TypeRef &&
c.cur_type().kind() == CXType_Unexposed
// Work around https://bugs.llvm.org/show_bug.cgi?id=42532, see:
// * https://github.com/rust-lang/rust-bindgen/issues/283
// * https://github.com/rust-lang/rust-bindgen/issues/1590
{
found_cant_eval = true;
CXChildVisit_Break
} else {
CXChildVisit_Recurse
});
if found_cant_eval {
return None;
}
let mut found_cant_eval = false;
cursor.visit(|c| {
if c.kind() == CXCursor_TypeRef &&
c.cur_type().canonical_type().kind() == CXType_Unexposed {
found_cant_eval = true;
return CXChildVisit_Break;
}

CXChildVisit_Recurse
});

if found_cant_eval {
return None;
}
}
Some(EvalResult {
x: unsafe { clang_Cursor_Evaluate(cursor.x) },
})
Expand Down
15 changes: 15 additions & 0 deletions tests/expectations/tests/eval-value-dependent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* automatically generated by rust-bindgen */

#![allow(
dead_code,
non_snake_case,
non_camel_case_types,
non_upper_case_globals
)]

#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct e {
pub _address: u8,
}
pub type e_f<d> = d;
6 changes: 6 additions & 0 deletions tests/headers/eval-value-dependent.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// bindgen-flags: -- -std=c++11

template <typename d> class e {
using f = d;
static const auto g = alignof(f);
};

0 comments on commit 6f92b1c

Please sign in to comment.