summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2019-07-09 15:34:07 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2019-07-09 17:02:09 +0200
commit6f92b1c1f2086dfe7b478290e76469e64d24bfbd (patch)
tree6b670776def0b722413a1273b598fa6cb0ab9dd7
parentd7898170fb8feadcab1940c2ecfbac2510780552 (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.rs36
-rw-r--r--tests/expectations/tests/eval-value-dependent.rs15
-rw-r--r--tests/headers/eval-value-dependent.hpp6
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);
+};