Skip to content

Commit 66b7747

Browse files
committed
Simplify handle_function_macro for clang 4.0+
1 parent bc7bd0e commit 66b7747

File tree

1 file changed

+22
-48
lines changed

1 file changed

+22
-48
lines changed

src/ir/var.rs

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -149,52 +149,27 @@ fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind {
149149
}
150150
}
151151

152-
/// Determines whether a set of tokens from a CXCursor_MacroDefinition
153-
/// represent a function-like macro. If so, calls the func_macro callback
154-
/// and returns `Err(ParseError::Continue)` to signal to skip further
155-
/// processing. If conversion to UTF-8 fails (it is performed only where it
156-
/// should be infallible), then `Err(ParseError::Continue)` is returned as well.
152+
/// Parses tokens from a CXCursor_MacroDefinition pointing into a function-like
153+
/// macro, and calls the func_macro callback.
157154
fn handle_function_macro(
158155
cursor: &clang::Cursor,
159-
tokens: &[ClangToken],
160156
callbacks: &dyn crate::callbacks::ParseCallbacks,
161-
) -> Result<(), ParseError> {
162-
// TODO: Hoist the `is_macro_function_like` check into this function's
163-
// caller, and thus avoid allocating the `tokens` vector for non-functional
164-
// macros.
165-
let is_functional_macro = cursor.is_macro_function_like();
166-
167-
if !is_functional_macro {
168-
return Ok(());
169-
}
170-
157+
) {
171158
let is_closing_paren = |t: &ClangToken| {
172159
// Test cheap token kind before comparing exact spellings.
173160
t.kind == clang_sys::CXToken_Punctuation && t.spelling() == b")"
174161
};
175-
let boundary = tokens.iter().position(is_closing_paren);
176-
177-
let mut spelled = tokens.iter().map(ClangToken::spelling);
178-
// Add 1, to convert index to length.
179-
let left = spelled
180-
.by_ref()
181-
.take(boundary.ok_or(ParseError::Continue)? + 1);
182-
let left = left.collect::<Vec<_>>().concat();
183-
let left = String::from_utf8(left).map_err(|_| ParseError::Continue)?;
184-
let right = spelled;
185-
// Drop last token with LLVM < 4.0, due to an LLVM bug.
186-
//
187-
// See:
188-
// https://bugs.llvm.org//show_bug.cgi?id=9069
189-
let len = match (right.len(), crate::clang_version().parsed) {
190-
(len, Some((v, _))) if len > 0 && v < 4 => len - 1,
191-
(len, _) => len,
192-
};
193-
let right: Vec<_> = right.take(len).collect();
194-
callbacks.func_macro(&left, &right);
195-
196-
// We handled the macro, skip future macro processing.
197-
Err(ParseError::Continue)
162+
let tokens: Vec<_> = cursor.tokens().iter().collect();
163+
if let Some(boundary) = tokens.iter().position(is_closing_paren) {
164+
let mut spelled = tokens.iter().map(ClangToken::spelling);
165+
// Add 1, to convert index to length.
166+
let left = spelled.by_ref().take(boundary + 1);
167+
let left = left.collect::<Vec<_>>().concat();
168+
if let Ok(left) = String::from_utf8(left) {
169+
let right: Vec<_> = spelled.collect();
170+
callbacks.func_macro(&left, &right);
171+
}
172+
}
198173
}
199174

200175
impl ClangSubItemParser for Var {
@@ -207,8 +182,6 @@ impl ClangSubItemParser for Var {
207182
use clang_sys::*;
208183
match cursor.kind() {
209184
CXCursor_MacroDefinition => {
210-
let tokens: Vec<_> = cursor.tokens().iter().collect();
211-
212185
if let Some(callbacks) = ctx.parse_callbacks() {
213186
match callbacks.will_parse_macro(&cursor.spelling()) {
214187
MacroParsingBehavior::Ignore => {
@@ -217,10 +190,14 @@ impl ClangSubItemParser for Var {
217190
MacroParsingBehavior::Default => {}
218191
}
219192

220-
handle_function_macro(&cursor, &tokens, callbacks)?;
193+
if cursor.is_macro_function_like() {
194+
handle_function_macro(&cursor, callbacks);
195+
// We handled the macro, skip macro processing below.
196+
return Err(ParseError::Continue);
197+
}
221198
}
222199

223-
let value = parse_macro(ctx, &tokens);
200+
let value = parse_macro(ctx, &cursor);
224201

225202
let (id, value) = match value {
226203
Some(v) => v,
@@ -387,14 +364,11 @@ impl ClangSubItemParser for Var {
387364
/// Try and parse a macro using all the macros parsed until now.
388365
fn parse_macro(
389366
ctx: &BindgenContext,
390-
tokens: &[ClangToken],
367+
cursor: &clang::Cursor,
391368
) -> Option<(Vec<u8>, cexpr::expr::EvalResult)> {
392369
use cexpr::expr;
393370

394-
let cexpr_tokens: Vec<_> = tokens
395-
.iter()
396-
.filter_map(ClangToken::as_cexpr_token)
397-
.collect();
371+
let cexpr_tokens = cursor.cexpr_tokens();
398372

399373
let parser = expr::IdentifierParser::new(ctx.parsed_macros());
400374

0 commit comments

Comments
 (0)