diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-11-21 12:41:14 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-21 12:41:14 -0600 |
commit | 94fff8339da07c7b45dea724a29c02c8fdc646f7 (patch) | |
tree | 853e617c2dd61284755578c60671d10866be7ecc /libbindgen/src | |
parent | c3ce5b1e3820f691856bf4c66890646c67676679 (diff) | |
parent | 1c18ec72b83a107c16d944e7c260855419eb7f3c (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.rs | 35 | ||||
-rw-r--r-- | libbindgen/src/ir/var.rs | 7 |
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 |