summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clang.rs72
-rw-r--r--src/ir/var.rs28
2 files changed, 47 insertions, 53 deletions
diff --git a/src/clang.rs b/src/clang.rs
index cdadce1c..6e1f426c 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -1361,55 +1361,31 @@ impl TranslationUnit {
-> Option<Vec<cexpr::token::Token>> {
use cexpr::token;
- let mut tokens = match self.tokens(cursor) {
- Some(tokens) => tokens,
- None => return None,
- };
-
- // FIXME(emilio): LLVM 3.9 at least always include an extra token for no
- // good reason (except if we're at EOF). So we do this kind of hack,
- // where we skip known-to-cause problems trailing punctuation and
- // trailing keywords.
- //
- // This is sort of unfortunate, though :(.
- //
- // I'll try to get it fixed in LLVM if I have the time to submit a
- // patch.
- let mut trim_last_token = false;
- if let Some(token) = tokens.last() {
- // The starting of the next macro.
- trim_last_token |= token.spelling == "#" &&
- token.kind == CXToken_Punctuation;
-
- // A following keyword of any kind, like a following declaration.
- trim_last_token |= token.kind == CXToken_Keyword;
- }
-
- if trim_last_token {
- tokens.pop().unwrap();
- }
-
- Some(tokens.into_iter()
- .filter_map(|token| {
- let kind = match token.kind {
- CXToken_Punctuation => token::Kind::Punctuation,
- CXToken_Literal => token::Kind::Literal,
- CXToken_Identifier => token::Kind::Identifier,
- CXToken_Keyword => token::Kind::Keyword,
- // NB: cexpr is not too happy about comments inside
- // expressions, so we strip them down here.
- CXToken_Comment => return None,
- _ => {
- panic!("Found unexpected token kind: {:?}", token.kind)
- }
- };
-
- Some(token::Token {
- kind: kind,
- raw: token.spelling.into_bytes().into_boxed_slice(),
+ self.tokens(cursor).map(|tokens| {
+ tokens
+ .into_iter()
+ .filter_map(|token| {
+ let kind = match token.kind {
+ CXToken_Punctuation => token::Kind::Punctuation,
+ CXToken_Literal => token::Kind::Literal,
+ CXToken_Identifier => token::Kind::Identifier,
+ CXToken_Keyword => token::Kind::Keyword,
+ // NB: cexpr is not too happy about comments inside
+ // expressions, so we strip them down here.
+ CXToken_Comment => return None,
+ _ => {
+ error!("Found unexpected token kind: {:?}", token);
+ return None
+ }
+ };
+
+ Some(token::Token {
+ kind: kind,
+ raw: token.spelling.into_bytes().into_boxed_slice(),
+ })
})
- })
- .collect::<Vec<_>>())
+ .collect::<Vec<_>>()
+ })
}
}
diff --git a/src/ir/var.rs b/src/ir/var.rs
index 656a1a6d..b1efc57a 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -284,17 +284,35 @@ fn parse_macro(ctx: &BindgenContext,
-> Option<(Vec<u8>, cexpr::expr::EvalResult)> {
use cexpr::{expr, nom};
- let cexpr_tokens = match unit.cexpr_tokens(cursor) {
+ let mut cexpr_tokens = match unit.cexpr_tokens(cursor) {
None => return None,
Some(tokens) => tokens,
};
let parser = expr::IdentifierParser::new(ctx.parsed_macros());
- let result = parser.macro_definition(&cexpr_tokens);
- match result {
- nom::IResult::Done(_, (id, val)) => Some((id.into(), val)),
- _ => None,
+ match parser.macro_definition(&cexpr_tokens) {
+ nom::IResult::Done(_, (id, val)) => {
+ return Some((id.into(), val));
+ }
+ _ => {}
+ }
+
+ // Try without the last token, to workaround a libclang bug in versions
+ // previous to 4.0.
+ //
+ // See:
+ // https://bugs.llvm.org//show_bug.cgi?id=9069
+ // https://reviews.llvm.org/D26446
+ if cexpr_tokens.pop().is_none() {
+ return None;
+ }
+
+ match parser.macro_definition(&cexpr_tokens) {
+ nom::IResult::Done(_, (id, val)) => {
+ Some((id.into(), val))
+ }
+ _ => None
}
}