diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-06-15 18:33:30 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-15 18:33:30 -0700 |
commit | 56a46b20b799962418a6c741439105f7e016c12c (patch) | |
tree | 06d12a9c691749875074dd182f046702f63b3192 /src | |
parent | df4dc8740c2bd0b37f3ed04d00314a8f8d89992e (diff) | |
parent | 9faf458562db820c83f74be580b741f6b7dfd913 (diff) |
Auto merge of #750 - emilio:that-bug-is-going-to-hunt-me-down, r=fitzgen
ir: Make the workaround for LLVM bug 9069 more reliable.
Should fix https://github.com/zzeroo/libmodbus-rs/issues/4
Diffstat (limited to 'src')
-rw-r--r-- | src/clang.rs | 72 | ||||
-rw-r--r-- | src/ir/var.rs | 28 |
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 } } |