diff options
author | Darren Kulp <darren@kulp.ch> | 2020-06-21 17:40:04 -0700 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2022-02-18 19:33:25 +0100 |
commit | c4532e0c1756e2df1c20dd67b781582f4289709b (patch) | |
tree | 106815f98ae3bb59330da5ee4e728d96bdac2dd8 /src | |
parent | 69ee6fb243f56648a66c492f5b7395bc37d59f06 (diff) |
parser: Simplify handle_function_macro for clang 4.0+
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/var.rs | 70 |
1 files changed, 22 insertions, 48 deletions
diff --git a/src/ir/var.rs b/src/ir/var.rs index 396b3e04..e44d57af 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -149,52 +149,27 @@ fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind { } } -/// 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 @@ impl ClangSubItemParser for Var { 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 @@ impl ClangSubItemParser for Var { 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 @@ impl ClangSubItemParser for Var { /// 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()); |