From 967c3783082c9183ceafc79659d400051f9e8e8d Mon Sep 17 00:00:00 2001 From: Hayes Neuman Date: Wed, 13 May 2020 09:04:26 -0400 Subject: [PATCH] Support casts in constants --- src/bindgen/ir/constant.rs | 30 ++++++++++++++++++++++- tests/expectations/both/constant.c | 4 +++ tests/expectations/both/constant.compat.c | 4 +++ tests/expectations/constant.c | 4 +++ tests/expectations/constant.compat.c | 4 +++ tests/expectations/constant.cpp | 4 +++ tests/expectations/tag/constant.c | 4 +++ tests/expectations/tag/constant.compat.c | 4 +++ tests/rust/constant.rs | 5 +++- 9 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index 9c7a140..1ae682d 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -37,6 +37,10 @@ pub enum Literal { export_name: String, fields: HashMap, }, + Cast { + ty: Type, + value: Box, + }, } impl Literal { @@ -45,7 +49,8 @@ impl Literal { Literal::PostfixUnaryOp { .. } | Literal::BinOp { .. } | Literal::Expr(..) - | Literal::Path(..) => {} + | Literal::Path(..) + | Literal::Cast { .. } => {} Literal::Struct { ref mut path, ref mut export_name, @@ -72,6 +77,7 @@ impl Literal { .. } => left.is_valid(bindings) && right.is_valid(bindings), Literal::Struct { ref path, .. } => bindings.struct_exists(path), + Literal::Cast { ref value, .. } => value.is_valid(bindings), } } } @@ -104,6 +110,9 @@ impl Literal { right.rename_for_config(config); } Literal::Expr(_) => {} + Literal::Cast { ref mut value, .. } => { + value.rename_for_config(config); + } } } @@ -229,6 +238,19 @@ impl Literal { syn::Expr::Paren(syn::ExprParen { ref expr, .. }) => Self::load(expr), + syn::Expr::Cast(syn::ExprCast { + ref expr, ref ty, .. + }) => { + let val = Self::load(expr)?; + match Type::load(ty)? { + Some(ty) => Ok(Literal::Cast { + ty, + value: Box::new(val), + }), + None => Err("Cannot cast to zero sized type.".to_owned()), + } + } + _ => Err(format!("Unsupported expression. {:?}", *expr)), } } @@ -252,6 +274,12 @@ impl Literal { right.write(config, out); write!(out, ")"); } + Literal::Cast { ref ty, ref value } => { + write!(out, "("); + ty.write(config, out); + write!(out, ")"); + value.write(config, out); + } Literal::Struct { export_name, fields, diff --git a/tests/expectations/both/constant.c b/tests/expectations/both/constant.c index b5045b9..bff720a 100644 --- a/tests/expectations/both/constant.c +++ b/tests/expectations/both/constant.c @@ -3,8 +3,12 @@ #include #include +#define CAST (uint8_t)'A' + #define DELIMITER ':' +#define DOUBLE_CAST (uint32_t)(float)1 + #define EQUID L'\U00010083' #define FOO 10 diff --git a/tests/expectations/both/constant.compat.c b/tests/expectations/both/constant.compat.c index 8dd0dfe..8a37efc 100644 --- a/tests/expectations/both/constant.compat.c +++ b/tests/expectations/both/constant.compat.c @@ -3,8 +3,12 @@ #include #include +#define CAST (uint8_t)'A' + #define DELIMITER ':' +#define DOUBLE_CAST (uint32_t)(float)1 + #define EQUID L'\U00010083' #define FOO 10 diff --git a/tests/expectations/constant.c b/tests/expectations/constant.c index 0ba126d..e6d52c1 100644 --- a/tests/expectations/constant.c +++ b/tests/expectations/constant.c @@ -3,8 +3,12 @@ #include #include +#define CAST (uint8_t)'A' + #define DELIMITER ':' +#define DOUBLE_CAST (uint32_t)(float)1 + #define EQUID L'\U00010083' #define FOO 10 diff --git a/tests/expectations/constant.compat.c b/tests/expectations/constant.compat.c index 13e17c4..212b9b2 100644 --- a/tests/expectations/constant.compat.c +++ b/tests/expectations/constant.compat.c @@ -3,8 +3,12 @@ #include #include +#define CAST (uint8_t)'A' + #define DELIMITER ':' +#define DOUBLE_CAST (uint32_t)(float)1 + #define EQUID L'\U00010083' #define FOO 10 diff --git a/tests/expectations/constant.cpp b/tests/expectations/constant.cpp index 6bee53b..965d268 100644 --- a/tests/expectations/constant.cpp +++ b/tests/expectations/constant.cpp @@ -3,8 +3,12 @@ #include #include +static const uint8_t CAST = (uint8_t)'A'; + static const uint32_t DELIMITER = ':'; +static const uint32_t DOUBLE_CAST = (uint32_t)(float)1; + static const uint32_t EQUID = L'\U00010083'; static const int32_t FOO = 10; diff --git a/tests/expectations/tag/constant.c b/tests/expectations/tag/constant.c index abfa088..82c1e5c 100644 --- a/tests/expectations/tag/constant.c +++ b/tests/expectations/tag/constant.c @@ -3,8 +3,12 @@ #include #include +#define CAST (uint8_t)'A' + #define DELIMITER ':' +#define DOUBLE_CAST (uint32_t)(float)1 + #define EQUID L'\U00010083' #define FOO 10 diff --git a/tests/expectations/tag/constant.compat.c b/tests/expectations/tag/constant.compat.c index 4275dca..1e4d63e 100644 --- a/tests/expectations/tag/constant.compat.c +++ b/tests/expectations/tag/constant.compat.c @@ -3,8 +3,12 @@ #include #include +#define CAST (uint8_t)'A' + #define DELIMITER ':' +#define DOUBLE_CAST (uint32_t)(float)1 + #define EQUID L'\U00010083' #define FOO 10 diff --git a/tests/rust/constant.rs b/tests/rust/constant.rs index 1c59a50..637a2ce 100644 --- a/tests/rust/constant.rs +++ b/tests/rust/constant.rs @@ -26,10 +26,13 @@ pub const XBOOL: i64 = 1; pub const XFALSE: i64 = (0 << SHIFT) | XBOOL; pub const XTRUE: i64 = 1 << (SHIFT | XBOOL); +pub const CAST: u8 = 'A' as u8; +pub const DOUBLE_CAST: u32 = 1 as f32 as u32; + #[repr(C)] struct Foo { x: [i32; FOO], } #[no_mangle] -pub extern "C" fn root(x: Foo) { } +pub extern "C" fn root(x: Foo) {}