summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-04-24 08:47:51 -0500
committerGitHub <noreply@github.com>2017-04-24 08:47:51 -0500
commit2af4f826579dc9e4f65e8934e77b25a77c711716 (patch)
tree6ddb9d26bd9fe526136c7074660c6d6d4e20c837
parentce8feb3262a26a24837a89a4702b606ebe705c8a (diff)
parent20d5140a1ac950a8499e357a51604c5032321cfd (diff)
Auto merge of #657 - emilio:cxx-mangling, r=fitzgen
ir: Try to get C++ manglings with the appropriate API first. As pointed out in #653, clang 3.8 asserts when trying to mangle a C++ constructor or a destructor. The following patch tries to use the `clang_Cursor_getCXXManglings` function first. This assumes that the last mangling we're interested in is the proper one, which seems to be true looking at LLVM, and on trunk on my machine. Fixes #653
-rw-r--r--src/clang.rs40
-rw-r--r--src/ir/function.rs6
2 files changed, 39 insertions, 7 deletions
diff --git a/src/clang.rs b/src/clang.rs
index b4acf204..cdadce1c 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -77,6 +77,30 @@ impl Cursor {
}
}
+ /// Gets the C++ manglings for this cursor, or an error if the function is
+ /// not loaded or the manglings are not available.
+ pub fn cxx_manglings(&self) -> Result<Vec<String>, ()> {
+ use clang_sys::*;
+ if !clang_Cursor_getCXXManglings::is_loaded() {
+ return Err(());
+ }
+ unsafe {
+ let manglings = clang_Cursor_getCXXManglings(self.x);
+ if manglings.is_null() {
+ return Err(());
+ }
+ let count = (*manglings).Count as usize;
+
+ let mut result = Vec::with_capacity(count);
+ for i in 0..count {
+ let string_ptr = (*manglings).Strings.offset(i as isize);
+ result.push(cxstring_to_string_leaky(*string_ptr));
+ }
+ clang_disposeStringSet(manglings);
+ Ok(result)
+ }
+ }
+
/// Returns whether the cursor refers to a built-in definition.
pub fn is_builtin(&self) -> bool {
let (file, _, _, _) = self.location().location();
@@ -1168,16 +1192,18 @@ impl File {
}
}
-fn cxstring_into_string(s: CXString) -> String {
+fn cxstring_to_string_leaky(s: CXString) -> String {
if s.data.is_null() {
return "".to_owned();
}
- unsafe {
- let c_str = CStr::from_ptr(clang_getCString(s) as *const _);
- let ret = c_str.to_string_lossy().into_owned();
- clang_disposeString(s);
- ret
- }
+ let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) };
+ c_str.to_string_lossy().into_owned()
+}
+
+fn cxstring_into_string(s: CXString) -> String {
+ let ret = cxstring_to_string_leaky(s);
+ unsafe { clang_disposeString(s) };
+ ret
}
/// An `Index` is an environment for a set of translation units that will
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 0809b3c2..23503b05 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -126,6 +126,12 @@ pub fn cursor_mangling(ctx: &BindgenContext,
return None;
}
+ if let Ok(mut manglings) = cursor.cxx_manglings() {
+ if let Some(m) = manglings.pop() {
+ return Some(m);
+ }
+ }
+
let mut mangling = cursor.mangling();
if mangling.is_empty() {
return None;