diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-02-01 18:59:33 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-02-02 13:03:49 +0100 |
commit | 993a95922c12fd4e46efa368e2a8b0807d38eff5 (patch) | |
tree | fe393e0b303509ea8a66c416fb06991ccab4e38f | |
parent | bdd034b07a02a1a886ac8b94a81327608f6124b3 (diff) |
ir: Fix is_in_non_fully_specialized_template check.
Fixes https://github.com/servo/rust-bindgen/issues/462
-rw-r--r-- | src/clang.rs | 16 | ||||
-rw-r--r-- | src/ir/function.rs | 2 | ||||
-rw-r--r-- | tests/expectations/tests/constant-non-specialized-tp.rs | 24 | ||||
-rw-r--r-- | tests/headers/constant-non-specialized-tp.hpp | 15 |
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... }; + }; +}; |