summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXidorn Quan <me@upsuper.org>2016-10-25 17:13:50 +1100
committerXidorn Quan <me@upsuper.org>2016-10-25 23:45:31 +1100
commitf798f6536da5ad7e5d850dff2e4546f5aac78cbb (patch)
tree4b779fed0c815f65fe1f8dd7bd814075442b4444
parent4e2b9d6f0ff3a02ed8ff97ac2ccd7a8e6bee273d (diff)
Handle octal and negative literals properly
-rw-r--r--src/ir/var.rs38
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 => {