From d934705e1a3d830a8829e41e0e1809fd88da5044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 13 Dec 2016 18:18:00 +0100 Subject: [PATCH] Use a dynamically loaded clang to do as much as we can with old clang versions, and experiment with new ones. It's a pity that we don't support clang 3.7 and similar for generating C bindings, when it should be straight-forward. This should allow us to support older clang versions, and also experiment with pre-release clang APIs if needed. This depends on: https://github.com/KyleMayes/clang-sys/pull/44 --- bindgen/Cargo.toml | 2 +- libbindgen/Cargo.toml | 2 +- libbindgen/src/clang.rs | 39 ++++++--------------------------------- libbindgen/src/ir/ty.rs | 1 - libbindgen/src/lib.rs | 9 +++++++++ 5 files changed, 17 insertions(+), 36 deletions(-) diff --git a/bindgen/Cargo.toml b/bindgen/Cargo.toml index 1ac99d0389..22e31ba6e6 100644 --- a/bindgen/Cargo.toml +++ b/bindgen/Cargo.toml @@ -15,7 +15,7 @@ version = "0.17.0" workspace = ".." [dependencies] -clang-sys = "0.11.1" +clang-sys = "0.12" clap = "2" libbindgen = { path = "../libbindgen" } log = "0.3" diff --git a/libbindgen/Cargo.toml b/libbindgen/Cargo.toml index d78cbc3bff..6e6b045511 100644 --- a/libbindgen/Cargo.toml +++ b/libbindgen/Cargo.toml @@ -26,7 +26,7 @@ quasi_codegen = "0.26" [dependencies] cexpr = "0.2" cfg-if = "0.1.0" -clang-sys = { version = "0.11.1", features = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8", "gte_clang_3_9"] } +clang-sys = { version = "0.12", features = ["runtime", "clang_3_9"] } lazy_static = "0.2.1" libc = "0.2" rustc-serialize = "0.3.19" diff --git a/libbindgen/src/clang.rs b/libbindgen/src/clang.rs index ad311835f0..3f272607df 100644 --- a/libbindgen/src/clang.rs +++ b/libbindgen/src/clang.rs @@ -349,19 +349,9 @@ impl Cursor { } /// Is the referent an inlined function? - #[cfg(not(feature="llvm_stable"))] pub fn is_inlined_function(&self) -> bool { - unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } - } - - // TODO: Remove this when LLVM 3.9 is released. - // - // This is currently used for CI purposes. - - /// Is the referent an inlined function? - #[cfg(feature="llvm_stable")] - pub fn is_inlined_function(&self) -> bool { - false + clang_Cursor_isFunctionInlined::is_loaded() && + unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } } /// Get the width of this cursor's referent bit field, or `None` if the @@ -762,7 +752,6 @@ impl Type { /// For elaborated types (types which use `class`, `struct`, or `union` to /// disambiguate types from local bindings), get the underlying type. - #[cfg(not(feature="llvm_stable"))] pub fn named(&self) -> Type { unsafe { Type { @@ -1306,28 +1295,13 @@ pub struct EvalResult { x: CXEvalResult, } -#[cfg(feature = "llvm_stable")] -impl EvalResult { - /// Create a dummy EvalResult. - pub fn new(_: Cursor) -> Option { - None - } - - /// Not useful in llvm 3.8. - pub fn as_double(&self) -> Option { - None - } - - /// Not useful in llvm 3.8. - pub fn as_int(&self) -> Option { - None - } -} - -#[cfg(not(feature = "llvm_stable"))] impl EvalResult { /// Evaluate `cursor` and return the result. pub fn new(cursor: Cursor) -> Option { + if !clang_Cursor_Evaluate::is_loaded() { + 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 @@ -1379,7 +1353,6 @@ impl EvalResult { } } -#[cfg(not(feature = "llvm_stable"))] impl Drop for EvalResult { fn drop(&mut self) { unsafe { clang_EvalResult_dispose(self.x) }; diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs index dde2176e70..58ac7c871f 100644 --- a/libbindgen/src/ir/ty.rs +++ b/libbindgen/src/ir/ty.rs @@ -854,7 +854,6 @@ impl Type { .expect("Not able to resolve array element?"); TypeKind::Array(inner, ty.num_elements().unwrap()) } - #[cfg(not(feature="llvm_stable"))] CXType_Elaborated => { return Self::from_clang_ty(potential_id, &ty.named(), diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs index 22972659df..4ef8b54ca9 100644 --- a/libbindgen/src/lib.rs +++ b/libbindgen/src/lib.rs @@ -511,6 +511,10 @@ impl<'ctx> Bindings<'ctx> { span: Option) -> Result, ()> { let span = span.unwrap_or(DUMMY_SP); + if !clang_sys::is_loaded() { + // TODO(emilio): Return meaningful error (breaking). + clang_sys::load().expect("Unable to find libclang"); + } // TODO: Make this path fixup configurable? if let Some(clang) = clang_sys::support::Clang::find(None) { @@ -691,6 +695,11 @@ pub struct ClangVersion { /// Get the major and the minor semvar numbers of Clang's version pub fn clang_version() -> ClangVersion { + if !clang_sys::is_loaded() { + // TODO(emilio): Return meaningful error (breaking). + clang_sys::load().expect("Unable to find libclang"); + } + let raw_v: String = clang::extract_clang_version(); let split_v: Option> = raw_v.split_whitespace() .nth(2)