From 2f134838d745cacb2f1ad72e6f061e7e296b3805 Mon Sep 17 00:00:00 2001 From: Ravi Shankar Date: Mon, 3 Oct 2016 20:36:47 +0530 Subject: [PATCH 1/2] Parse negative integers appropriately --- src/clang.rs | 1 + src/ir/var.rs | 41 ++++++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index f98644ceff..e5943b6fbc 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -735,6 +735,7 @@ impl Drop for Index { } // Token +#[derive(Debug)] pub struct Token { pub kind: CXTokenKind, pub spelling: String, diff --git a/src/ir/var.rs b/src/ir/var.rs index ac59973bcb..23529bcde0 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -64,7 +64,7 @@ impl ClangSubItemParser for Var { use clangll::*; match cursor.kind() { CXCursor_MacroDefinition => { - let value = match parse_int_literal_tokens(&cursor, context.translation_unit(), 1) { + let value = match parse_int_literal_tokens(&cursor, context.translation_unit()) { None => return Err(ParseError::Continue), Some(v) => v, }; @@ -81,7 +81,9 @@ impl ClangSubItemParser for Var { } context.note_parsed_macro(name.clone()); - let ty = if value.abs() > u32::max_value() as i64 { + let ty = if value < 0 { + Item::builtin_type(TypeKind::Int(IntKind::Int), true, context) + } else if value.abs() > u32::max_value() as i64 { Item::builtin_type(TypeKind::Int(IntKind::ULongLong), true, context) } else { Item::builtin_type(TypeKind::Int(IntKind::UInt), true, context) @@ -114,10 +116,7 @@ impl ClangSubItemParser for Var { // Try to parse a literal token value cursor.visit(|c, _| { if c.kind() == CXCursor_IntegerLiteral { - value = - parse_int_literal_tokens(&c, - context.translation_unit(), - 0); + value = parse_int_literal_tokens(&c, context.translation_unit()); } CXChildVisit_Continue }); @@ -137,24 +136,36 @@ impl ClangSubItemParser for Var { } } +/// Try and parse the immediately found tokens from an unit (if any) to integers fn parse_int_literal_tokens(cursor: &clang::Cursor, - unit: &clang::TranslationUnit, - which: usize) -> Option { - use clangll::CXToken_Literal; + unit: &clang::TranslationUnit) -> Option { + use clangll::{CXToken_Literal, CXToken_Punctuation}; + + let mut lit = String::new(); let tokens = match unit.tokens(cursor) { None => return None, Some(tokens) => tokens, }; - if tokens.len() <= which || tokens[which].kind != CXToken_Literal { - return None; + for token in tokens { + 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); + }, + CXToken_Literal => { + lit.push_str(&token.spelling); + break + }, + _ => (), + } } - let s = &tokens[which].spelling; // TODO: try to preserve hex literals? - if s.starts_with("0x") { - i64::from_str_radix(&s[2..], 16).ok() + if lit.starts_with("0x") { + i64::from_str_radix(&lit[2..], 16).ok() } else { - s.parse().ok() + lit.parse().ok() } } From 7a392534d180afdbaec9955ae3afd45a4196812a Mon Sep 17 00:00:00 2001 From: Ravi Shankar Date: Tue, 4 Oct 2016 08:32:24 +0530 Subject: [PATCH 2/2] Add test for 'int' in whitelist_vars and regen test expectations --- tests/expectations/jsval_layout_opaque.rs | 39 ++++++++++++----------- tests/expectations/whitelist_vars.rs | 10 ++++++ tests/headers/whitelist_vars.h | 4 +++ 3 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 tests/expectations/whitelist_vars.rs create mode 100644 tests/headers/whitelist_vars.h diff --git a/tests/expectations/jsval_layout_opaque.rs b/tests/expectations/jsval_layout_opaque.rs index dd432232d3..dc0ecad5de 100644 --- a/tests/expectations/jsval_layout_opaque.rs +++ b/tests/expectations/jsval_layout_opaque.rs @@ -24,6 +24,7 @@ impl ::std::clone::Clone for __BindgenUnionField { fn clone(&self) -> Self { Self::new() } } impl ::std::marker::Copy for __BindgenUnionField { } +pub const JSVAL_ALIGNMENT: ::std::os::raw::c_uint = 8; pub const JSVAL_TAG_SHIFT: ::std::os::raw::c_uint = 47; #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -93,8 +94,8 @@ pub enum JSWhyMagic { #[derive(Debug, Copy)] pub struct jsval_layout { pub asBits: __BindgenUnionField, - pub debugView: __BindgenUnionField, - pub s: __BindgenUnionField, + pub debugView: __BindgenUnionField, + pub s: __BindgenUnionField, pub asDouble: __BindgenUnionField, pub asPtr: __BindgenUnionField<*mut ::std::os::raw::c_void>, pub asWord: __BindgenUnionField, @@ -103,20 +104,20 @@ pub struct jsval_layout { } #[repr(C)] #[derive(Debug, Copy)] -pub struct jsval_layout__bindgen_ty_bindgen_id_89 { +pub struct jsval_layout__bindgen_ty_bindgen_id_90 { pub _bitfield_1: u64, } #[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_89() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_90() { + assert_eq!(::std::mem::size_of::() , 8usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 8usize); } -impl Clone for jsval_layout__bindgen_ty_bindgen_id_89 { +impl Clone for jsval_layout__bindgen_ty_bindgen_id_90 { fn clone(&self) -> Self { *self } } -impl jsval_layout__bindgen_ty_bindgen_id_89 { +impl jsval_layout__bindgen_ty_bindgen_id_90 { #[inline] pub fn payload47(&self) -> u64 { unsafe { @@ -149,36 +150,36 @@ impl jsval_layout__bindgen_ty_bindgen_id_89 { } #[repr(C)] #[derive(Debug, Copy)] -pub struct jsval_layout__bindgen_ty_bindgen_id_96 { - pub payload: jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97, +pub struct jsval_layout__bindgen_ty_bindgen_id_97 { + pub payload: jsval_layout__bindgen_ty_bindgen_id_97__bindgen_ty_bindgen_id_98, } #[repr(C)] #[derive(Debug, Copy)] -pub struct jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97 { +pub struct jsval_layout__bindgen_ty_bindgen_id_97__bindgen_ty_bindgen_id_98 { pub i32: __BindgenUnionField, pub u32: __BindgenUnionField, pub why: __BindgenUnionField, pub bindgen_union_field: u32, } #[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_97__bindgen_ty_bindgen_id_98() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 4usize); } impl Clone for - jsval_layout__bindgen_ty_bindgen_id_96__bindgen_ty_bindgen_id_97 { + jsval_layout__bindgen_ty_bindgen_id_97__bindgen_ty_bindgen_id_98 { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_96() { - assert_eq!(::std::mem::size_of::() +fn bindgen_test_layout_jsval_layout__bindgen_ty_bindgen_id_97() { + assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() + assert_eq!(::std::mem::align_of::() , 4usize); } -impl Clone for jsval_layout__bindgen_ty_bindgen_id_96 { +impl Clone for jsval_layout__bindgen_ty_bindgen_id_97 { fn clone(&self) -> Self { *self } } impl Clone for jsval_layout { diff --git a/tests/expectations/whitelist_vars.rs b/tests/expectations/whitelist_vars.rs new file mode 100644 index 0000000000..f7af24b256 --- /dev/null +++ b/tests/expectations/whitelist_vars.rs @@ -0,0 +1,10 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +pub const NONE: ::std::os::raw::c_uint = 0; +pub const FOO: ::std::os::raw::c_uint = 5; +pub const FOOB: ::std::os::raw::c_int = -2; +pub const FOOBAR: ::std::os::raw::c_int = -10; diff --git a/tests/headers/whitelist_vars.h b/tests/headers/whitelist_vars.h new file mode 100644 index 0000000000..07fa2815e7 --- /dev/null +++ b/tests/headers/whitelist_vars.h @@ -0,0 +1,4 @@ +#define NONE 0 +#define FOO 5 +#define FOOB -2 +#define FOOBAR (-10)