diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-07-09 15:34:07 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-07-09 17:02:09 +0200 |
commit | 6f92b1c1f2086dfe7b478290e76469e64d24bfbd (patch) | |
tree | 6b670776def0b722413a1273b598fa6cb0ab9dd7 | |
parent | d7898170fb8feadcab1940c2ecfbac2510780552 (diff) |
Improve workaround for LLVM bug when evaluating value-dependent expressions.
Using the canonical type makes it work across typedefs.
Fixes #1590
-rw-r--r-- | src/clang.rs | 36 | ||||
-rw-r--r-- | tests/expectations/tests/eval-value-dependent.rs | 15 | ||||
-rw-r--r-- | tests/headers/eval-value-dependent.hpp | 6 |
3 files changed, 38 insertions, 19 deletions
diff --git a/src/clang.rs b/src/clang.rs index e02d363f..b470e224 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -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) }, }) diff --git a/tests/expectations/tests/eval-value-dependent.rs b/tests/expectations/tests/eval-value-dependent.rs new file mode 100644 index 00000000..b290a2e6 --- /dev/null +++ b/tests/expectations/tests/eval-value-dependent.rs @@ -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; diff --git a/tests/headers/eval-value-dependent.hpp b/tests/headers/eval-value-dependent.hpp new file mode 100644 index 00000000..0f4dc6ab --- /dev/null +++ b/tests/headers/eval-value-dependent.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: -- -std=c++11 + +template <typename d> class e { + using f = d; + static const auto g = alignof(f); +}; |