diff options
-rw-r--r-- | src/ir/var.rs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/ir/var.rs b/src/ir/var.rs index c7091a5c..623a0636 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -137,33 +137,42 @@ fn parse_int_literal_tokens(cursor: &clang::Cursor, unit: &clang::TranslationUnit) -> Option<i64> { use clangll::{CXToken_Literal, CXToken_Punctuation}; - let mut lit = String::new(); let tokens = match unit.tokens(cursor) { None => return None, Some(tokens) => tokens, }; - for token in tokens { + let mut literal = None; + let mut negate = false; + for token in tokens.into_iter() { match token.kind { CXToken_Punctuation if token.spelling == "-" => { - // If there's ever any punctuation, we only need to worry about - // unary minus '-' (for now) - lit.push_str(&token.spelling); + negate = !negate; }, CXToken_Literal => { - lit.push_str(&token.spelling); + literal = Some(token.spelling); break }, - _ => (), + _ => { + // Reset values if we found anything else + negate = false; + literal = None; + } } } - // TODO: try to preserve hex literals? - if lit.starts_with("0x") { - i64::from_str_radix(&lit[2..], 16).ok() - } else { - lit.parse().ok() - } + literal.and_then(|lit| { + if lit.starts_with("0x") { + // TODO: try to preserve hex literals? + i64::from_str_radix(&lit[2..], 16).ok() + } else if lit == "0" { + Some(0) + } else if lit.starts_with("0") { + i64::from_str_radix(&lit[1..], 8).ok() + } else { + lit.parse().ok() + } + }).map(|lit| if negate { -lit } else { lit }) } fn get_integer_literal_from_cursor(cursor: &clang::Cursor, @@ -172,7 +181,8 @@ fn get_integer_literal_from_cursor(cursor: &clang::Cursor, let mut value = None; cursor.visit(|c, _| { match c.kind() { - CXCursor_IntegerLiteral => { + CXCursor_IntegerLiteral | + CXCursor_UnaryOperator => { value = parse_int_literal_tokens(&c, unit); } CXCursor_UnexposedExpr => { |