summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-11-21 12:41:14 -0600
committerGitHub <noreply@github.com>2016-11-21 12:41:14 -0600
commit94fff8339da07c7b45dea724a29c02c8fdc646f7 (patch)
tree853e617c2dd61284755578c60671d10866be7ecc /libbindgen/src
parentc3ce5b1e3820f691856bf4c66890646c67676679 (diff)
parent1c18ec72b83a107c16d944e7c260855419eb7f3c (diff)
Auto merge of #284 - fitzgen:dont-eval-variadic-templates, r=emilio
Do not evaluate variadic template types This is a workaround for an internal clang assertion that gets triggered if we try to evaluate a variadic template type reference. Fixes #283 r? @emilio
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/clang.rs35
-rw-r--r--libbindgen/src/ir/var.rs7
2 files changed, 31 insertions, 11 deletions
diff --git a/libbindgen/src/clang.rs b/libbindgen/src/clang.rs
index 6c95b22f..a11903aa 100644
--- a/libbindgen/src/clang.rs
+++ b/libbindgen/src/clang.rs
@@ -487,7 +487,7 @@ impl Cursor {
}
/// Try to evaluate this cursor.
- pub fn evaluate(&self) -> EvalResult {
+ pub fn evaluate(&self) -> Option<EvalResult> {
EvalResult::new(*self)
}
}
@@ -1286,10 +1286,8 @@ pub struct EvalResult {
#[cfg(feature = "llvm_stable")]
impl EvalResult {
/// Create a dummy EvalResult.
- pub fn new(_: Cursor) -> Self {
- EvalResult {
- x: ptr::null_mut(),
- }
+ pub fn new(_: Cursor) -> Option<Self> {
+ None
}
/// Not useful in llvm 3.8.
@@ -1306,10 +1304,31 @@ impl EvalResult {
#[cfg(not(feature = "llvm_stable"))]
impl EvalResult {
/// Evaluate `cursor` and return the result.
- pub fn new(cursor: Cursor) -> Self {
- EvalResult {
- x: unsafe { clang_Cursor_Evaluate(cursor.x) },
+ pub fn new(cursor: Cursor) -> Option<Self> {
+ // 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
+ // *also* doesn't expose any API for finding variadic vs non-variadic
+ // template type references, let alone whether a type referenced is a
+ // template type, instead they seem to show up as type references to an
+ // unexposed type. Our solution is to just flat out ban all
+ // `CXType_Unexposed` from evaluation.
+ let mut found_cant_eval = false;
+ cursor.visit(|c| {
+ if c.kind() == CXCursor_TypeRef && c.cur_type().kind() == CXType_Unexposed {
+ found_cant_eval = true;
+ CXChildVisit_Break
+ } else {
+ CXChildVisit_Recurse
+ }
+ });
+ if found_cant_eval {
+ return None;
}
+
+ Some(EvalResult {
+ x: unsafe { clang_Cursor_Evaluate(cursor.x) },
+ })
}
fn kind(&self) -> Enum_CXEvalResultKind {
diff --git a/libbindgen/src/ir/var.rs b/libbindgen/src/ir/var.rs
index bbaea939..b819bfa4 100644
--- a/libbindgen/src/ir/var.rs
+++ b/libbindgen/src/ir/var.rs
@@ -209,8 +209,9 @@ impl ClangSubItemParser for Var {
_ => unreachable!(),
};
- let mut val =
- cursor.evaluate().as_int().map(|val| val as i64);
+ let mut val = cursor.evaluate()
+ .and_then(|v| v.as_int())
+ .map(|val| val as i64);
if val.is_none() || !kind.signedness_matches(val.unwrap()) {
let tu = ctx.translation_unit();
val = get_integer_literal_from_cursor(&cursor, tu);
@@ -225,7 +226,7 @@ impl ClangSubItemParser for Var {
})
} else if is_float {
cursor.evaluate()
- .as_double()
+ .and_then(|v| v.as_double())
.map(VarType::Float)
} else {
None