parser: Simplify handle_function_macro for clang 4.0+
diff --git a/src/ir/var.rs b/src/ir/var.rs
index 396b3e0..e44d57a 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -149,52 +149,27 @@
}
}
-/// Determines whether a set of tokens from a CXCursor_MacroDefinition
-/// represent a function-like macro. If so, calls the func_macro callback
-/// and returns `Err(ParseError::Continue)` to signal to skip further
-/// processing. If conversion to UTF-8 fails (it is performed only where it
-/// should be infallible), then `Err(ParseError::Continue)` is returned as well.
+/// Parses tokens from a CXCursor_MacroDefinition pointing into a function-like
+/// macro, and calls the func_macro callback.
fn handle_function_macro(
cursor: &clang::Cursor,
- tokens: &[ClangToken],
callbacks: &dyn crate::callbacks::ParseCallbacks,
-) -> Result<(), ParseError> {
- // TODO: Hoist the `is_macro_function_like` check into this function's
- // caller, and thus avoid allocating the `tokens` vector for non-functional
- // macros.
- let is_functional_macro = cursor.is_macro_function_like();
-
- if !is_functional_macro {
- return Ok(());
- }
-
+) {
let is_closing_paren = |t: &ClangToken| {
// Test cheap token kind before comparing exact spellings.
t.kind == clang_sys::CXToken_Punctuation && t.spelling() == b")"
};
- let boundary = tokens.iter().position(is_closing_paren);
-
- let mut spelled = tokens.iter().map(ClangToken::spelling);
- // Add 1, to convert index to length.
- let left = spelled
- .by_ref()
- .take(boundary.ok_or(ParseError::Continue)? + 1);
- let left = left.collect::<Vec<_>>().concat();
- let left = String::from_utf8(left).map_err(|_| ParseError::Continue)?;
- let right = spelled;
- // Drop last token with LLVM < 4.0, due to an LLVM bug.
- //
- // See:
- // https://bugs.llvm.org//show_bug.cgi?id=9069
- let len = match (right.len(), crate::clang_version().parsed) {
- (len, Some((v, _))) if len > 0 && v < 4 => len - 1,
- (len, _) => len,
- };
- let right: Vec<_> = right.take(len).collect();
- callbacks.func_macro(&left, &right);
-
- // We handled the macro, skip future macro processing.
- Err(ParseError::Continue)
+ let tokens: Vec<_> = cursor.tokens().iter().collect();
+ if let Some(boundary) = tokens.iter().position(is_closing_paren) {
+ let mut spelled = tokens.iter().map(ClangToken::spelling);
+ // Add 1, to convert index to length.
+ let left = spelled.by_ref().take(boundary + 1);
+ let left = left.collect::<Vec<_>>().concat();
+ if let Ok(left) = String::from_utf8(left) {
+ let right: Vec<_> = spelled.collect();
+ callbacks.func_macro(&left, &right);
+ }
+ }
}
impl ClangSubItemParser for Var {
@@ -207,8 +182,6 @@
use clang_sys::*;
match cursor.kind() {
CXCursor_MacroDefinition => {
- let tokens: Vec<_> = cursor.tokens().iter().collect();
-
if let Some(callbacks) = ctx.parse_callbacks() {
match callbacks.will_parse_macro(&cursor.spelling()) {
MacroParsingBehavior::Ignore => {
@@ -217,10 +190,14 @@
MacroParsingBehavior::Default => {}
}
- handle_function_macro(&cursor, &tokens, callbacks)?;
+ if cursor.is_macro_function_like() {
+ handle_function_macro(&cursor, callbacks);
+ // We handled the macro, skip macro processing below.
+ return Err(ParseError::Continue);
+ }
}
- let value = parse_macro(ctx, &tokens);
+ let value = parse_macro(ctx, &cursor);
let (id, value) = match value {
Some(v) => v,
@@ -387,14 +364,11 @@
/// Try and parse a macro using all the macros parsed until now.
fn parse_macro(
ctx: &BindgenContext,
- tokens: &[ClangToken],
+ cursor: &clang::Cursor,
) -> Option<(Vec<u8>, cexpr::expr::EvalResult)> {
use cexpr::expr;
- let cexpr_tokens: Vec<_> = tokens
- .iter()
- .filter_map(ClangToken::as_cexpr_token)
- .collect();
+ let cexpr_tokens = cursor.cexpr_tokens();
let parser = expr::IdentifierParser::new(ctx.parsed_macros());