diff options
Diffstat (limited to 'libbindgen/src')
-rw-r--r-- | libbindgen/src/clang.rs | 52 | ||||
-rw-r--r-- | libbindgen/src/clangll.rs | 6 | ||||
-rw-r--r-- | libbindgen/src/ir/var.rs | 22 |
3 files changed, 74 insertions, 6 deletions
diff --git a/libbindgen/src/clang.rs b/libbindgen/src/clang.rs index 15f288dd..fb495929 100644 --- a/libbindgen/src/clang.rs +++ b/libbindgen/src/clang.rs @@ -475,6 +475,11 @@ impl Cursor { pub fn is_virtual_base(&self) -> bool { unsafe { clang_isVirtualBase(self.x) != 0 } } + + /// Try to evaluate this cursor. + pub fn evaluate(&self) -> EvalResult { + EvalResult::new(*self) + } } extern "C" fn visit_children<Visitor>(cur: CXCursor, @@ -1261,3 +1266,50 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult { pub fn extract_clang_version() -> String { unsafe { clang_getClangVersion().into() } } + +#[derive(Debug)] +pub struct EvalResult { + x: CXEvalResult, +} + +#[cfg(feature = "llvm_stable")] +impl EvalResult { + pub fn new(_: Cursor) -> Self { + EvalResult { + x: ::std::ptr::null_mut(), + } + } + + pub fn as_int(&self) -> Option<i32> { + None + } +} + +#[cfg(not(feature = "llvm_stable"))] +impl EvalResult { + pub fn new(cursor: Cursor) -> Self { + EvalResult { + x: unsafe { clang_Cursor_Evaluate(cursor.x) }, + } + } + + pub fn kind(&self) -> Enum_CXEvalResultKind { + unsafe { clang_EvalResult_getKind(self.x) } + } + + pub fn as_int(&self) -> Option<i32> { + match self.kind() { + CXEval_Int => { + Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i32) + } + _ => None, + } + } +} + +#[cfg(not(feature = "llvm_stable"))] +impl Drop for EvalResult { + fn drop(&mut self) { + unsafe { clang_EvalResult_dispose(self.x) }; + } +} diff --git a/libbindgen/src/clangll.rs b/libbindgen/src/clangll.rs index 98ba525c..e37baf25 100644 --- a/libbindgen/src/clangll.rs +++ b/libbindgen/src/clangll.rs @@ -1451,10 +1451,16 @@ extern "C" { offset: *mut c_uint); pub fn clang_indexLoc_getCXSourceLocation(loc: CXIdxLoc) -> CXSourceLocation; + #[cfg(not(feature="llvm_stable"))] pub fn clang_Cursor_Evaluate(C: CXCursor) -> CXEvalResult; + #[cfg(not(feature="llvm_stable"))] pub fn clang_EvalResult_getKind(E: CXEvalResult) -> Enum_CXEvalResultKind; + #[cfg(not(feature="llvm_stable"))] pub fn clang_EvalResult_getAsInt(E: CXEvalResult) -> c_int; + #[cfg(not(feature="llvm_stable"))] pub fn clang_EvalResult_getAsDouble(E: CXEvalResult) -> c_double; + #[cfg(not(feature="llvm_stable"))] pub fn clang_EvalResult_getAsStr(E: CXEvalResult) -> *const c_char; + #[cfg(not(feature="llvm_stable"))] pub fn clang_EvalResult_dispose(E: CXEvalResult); } diff --git a/libbindgen/src/ir/var.rs b/libbindgen/src/ir/var.rs index d0c4d9ca..c4f1f750 100644 --- a/libbindgen/src/ir/var.rs +++ b/libbindgen/src/ir/var.rs @@ -159,13 +159,23 @@ impl ClangSubItemParser for Var { // tests/headers/inner_const.hpp // // That's fine because in that case we know it's not a literal. - let value = ctx.safe_resolve_type(ty) + let is_integer = ctx.safe_resolve_type(ty) .and_then(|t| t.safe_canonical_type(ctx)) - .and_then(|t| if t.is_integer() { Some(t) } else { None }) - .and_then(|_| { - get_integer_literal_from_cursor(&cursor, - ctx.translation_unit()) - }); + .map(|t| t.is_integer()) + .unwrap_or(false); + + let value = if is_integer { + cursor.evaluate() + .as_int() + .map(|val| val as i64) + .or_else(|| { + let tu = ctx.translation_unit(); + get_integer_literal_from_cursor(&cursor, tu) + }) + } else { + None + }; + let mangling = cursor_mangling(&cursor); |