summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-02-01 18:59:33 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-02-02 13:03:49 +0100
commit993a95922c12fd4e46efa368e2a8b0807d38eff5 (patch)
treefe393e0b303509ea8a66c416fb06991ccab4e38f
parentbdd034b07a02a1a886ac8b94a81327608f6124b3 (diff)
ir: Fix is_in_non_fully_specialized_template check.
Fixes https://github.com/servo/rust-bindgen/issues/462
-rw-r--r--src/clang.rs16
-rw-r--r--src/ir/function.rs2
-rw-r--r--tests/expectations/tests/constant-non-specialized-tp.rs24
-rw-r--r--tests/headers/constant-non-specialized-tp.hpp15
4 files changed, 52 insertions, 5 deletions
diff --git a/src/clang.rs b/src/clang.rs
index 9cf51436..b659343e 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -201,14 +201,14 @@ impl Cursor {
}
/// Is the referent a template specialization?
- pub fn is_template(&self) -> bool {
+ pub fn is_template_specialization(&self) -> bool {
self.specialized().is_some()
}
/// Is the referent a fully specialized template specialization without any
/// remaining free template arguments?
pub fn is_fully_specialized_template(&self) -> bool {
- self.is_template() && self.num_template_args().unwrap_or(0) > 0
+ self.is_template_specialization() && self.num_template_args().unwrap_or(0) > 0
}
/// Is the referent a template specialization that still has remaining free
@@ -217,9 +217,17 @@ impl Cursor {
if self.is_toplevel() {
return false;
}
+
let parent = self.semantic_parent();
- (parent.is_template() && !parent.is_fully_specialized_template()) ||
- parent.is_in_non_fully_specialized_template()
+ if parent.is_fully_specialized_template() {
+ return false;
+ }
+
+ if !parent.is_template_like() {
+ return parent.is_in_non_fully_specialized_template();
+ }
+
+ return true;
}
/// Is this cursor pointing a valid referent?
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 6e205f1b..a50edfde 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -93,7 +93,7 @@ fn get_abi(cc: CXCallingConv) -> abi::Abi {
pub fn cursor_mangling(cursor: &clang::Cursor) -> Option<String> {
// We early return here because libclang may crash in some case
// if we pass in a variable inside a partial specialized template.
- // See servo/rust-bindgen#67.
+ // See servo/rust-bindgen#67, and servo/rust-bindgen#462.
if cursor.is_in_non_fully_specialized_template() {
return None;
}
diff --git a/tests/expectations/tests/constant-non-specialized-tp.rs b/tests/expectations/tests/constant-non-specialized-tp.rs
new file mode 100644
index 00000000..bbadf8a2
--- /dev/null
+++ b/tests/expectations/tests/constant-non-specialized-tp.rs
@@ -0,0 +1,24 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Test<Args> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<Args>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Outer<T> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Outer_Inner<T> {
+ pub _address: u8,
+ pub _phantom_0: ::std::marker::PhantomData<T>,
+}
diff --git a/tests/headers/constant-non-specialized-tp.hpp b/tests/headers/constant-non-specialized-tp.hpp
new file mode 100644
index 00000000..539c2887
--- /dev/null
+++ b/tests/headers/constant-non-specialized-tp.hpp
@@ -0,0 +1,15 @@
+// bindgen-flags: -- -std=c++11
+
+// This test ensure we protect ourselves from an LLVM crash.
+
+template <class... Args>
+struct Test {
+ static constexpr bool x[] = {Args::x...};
+};
+
+template<typename... T>
+struct Outer {
+ struct Inner {
+ static constexpr int value[] = { T::value... };
+ };
+};