summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/clang.rs52
-rw-r--r--libbindgen/src/clangll.rs6
-rw-r--r--libbindgen/src/ir/var.rs22
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);