From 6439e6df563786d8f834579a00ffd5c418244cd3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 3 Oct 2020 20:49:38 +0300 Subject: [PATCH] Support constants with arbitrary types --- src/bindgen/ir/constant.rs | 19 +---------------- .../both/constant_user_defined_type.c | 20 ++++++++++++++++++ .../both/constant_user_defined_type.compat.c | 20 ++++++++++++++++++ .../expectations/constant_user_defined_type.c | 20 ++++++++++++++++++ .../constant_user_defined_type.compat.c | 20 ++++++++++++++++++ .../constant_user_defined_type.cpp | 21 +++++++++++++++++++ .../tag/constant_user_defined_type.c | 20 ++++++++++++++++++ .../tag/constant_user_defined_type.compat.c | 20 ++++++++++++++++++ tests/rust/constant_user_defined_type.rs | 17 +++++++++++++++ 9 files changed, 159 insertions(+), 18 deletions(-) create mode 100644 tests/expectations/both/constant_user_defined_type.c create mode 100644 tests/expectations/both/constant_user_defined_type.compat.c create mode 100644 tests/expectations/constant_user_defined_type.c create mode 100644 tests/expectations/constant_user_defined_type.compat.c create mode 100644 tests/expectations/constant_user_defined_type.cpp create mode 100644 tests/expectations/tag/constant_user_defined_type.c create mode 100644 tests/expectations/tag/constant_user_defined_type.compat.c create mode 100644 tests/rust/constant_user_defined_type.rs diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index e199c39..8978f22 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -195,12 +195,9 @@ impl Literal { }) } - // Match literals like "one", 'a', 32 etc + // Match literals like true, 'a', 32 etc syn::Expr::Lit(syn::ExprLit { ref lit, .. }) => { match lit { - syn::Lit::Str(ref value) => { - Ok(Literal::Expr(format!("u8\"{}\"", value.value()))) - } syn::Lit::Byte(ref value) => Ok(Literal::Expr(format!("{}", value.value()))), syn::Lit::Char(ref value) => Ok(Literal::Expr(match value.value() as u32 { 0..=255 => format!("'{}'", value.value().escape_default()), @@ -363,16 +360,6 @@ pub struct Constant { pub associated_to: Option, } -fn can_handle(ty: &Type, expr: &syn::Expr) -> bool { - if ty.is_primitive_or_ptr_primitive() { - return true; - } - match *expr { - syn::Expr::Struct(_) => true, - _ => false, - } -} - impl Constant { pub fn load( path: Path, @@ -390,10 +377,6 @@ impl Constant { } }; - if !can_handle(&ty, expr) { - return Err("Unhandled const definition".to_owned()); - } - let mut lit = Literal::load(&expr)?; if let Some(ref associated_to) = associated_to { diff --git a/tests/expectations/both/constant_user_defined_type.c b/tests/expectations/both/constant_user_defined_type.c new file mode 100644 index 0000000..102789b --- /dev/null +++ b/tests/expectations/both/constant_user_defined_type.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef enum E { + V, +} E; + +typedef struct S { + uint8_t field; +} S; + +typedef uint8_t A; + +#define C1 (S){ .field = 0 } + +#define C2 V + +#define C3 0 diff --git a/tests/expectations/both/constant_user_defined_type.compat.c b/tests/expectations/both/constant_user_defined_type.compat.c new file mode 100644 index 0000000..102789b --- /dev/null +++ b/tests/expectations/both/constant_user_defined_type.compat.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef enum E { + V, +} E; + +typedef struct S { + uint8_t field; +} S; + +typedef uint8_t A; + +#define C1 (S){ .field = 0 } + +#define C2 V + +#define C3 0 diff --git a/tests/expectations/constant_user_defined_type.c b/tests/expectations/constant_user_defined_type.c new file mode 100644 index 0000000..d0eb1ad --- /dev/null +++ b/tests/expectations/constant_user_defined_type.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef enum { + V, +} E; + +typedef struct { + uint8_t field; +} S; + +typedef uint8_t A; + +#define C1 (S){ .field = 0 } + +#define C2 V + +#define C3 0 diff --git a/tests/expectations/constant_user_defined_type.compat.c b/tests/expectations/constant_user_defined_type.compat.c new file mode 100644 index 0000000..d0eb1ad --- /dev/null +++ b/tests/expectations/constant_user_defined_type.compat.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +typedef enum { + V, +} E; + +typedef struct { + uint8_t field; +} S; + +typedef uint8_t A; + +#define C1 (S){ .field = 0 } + +#define C2 V + +#define C3 0 diff --git a/tests/expectations/constant_user_defined_type.cpp b/tests/expectations/constant_user_defined_type.cpp new file mode 100644 index 0000000..c00e83f --- /dev/null +++ b/tests/expectations/constant_user_defined_type.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +enum E { + V, +}; + +struct S { + uint8_t field; +}; + +using A = uint8_t; + +static const S C1 = S{ /* .field = */ 0 }; + +static const E C2 = V; + +static const A C3 = 0; diff --git a/tests/expectations/tag/constant_user_defined_type.c b/tests/expectations/tag/constant_user_defined_type.c new file mode 100644 index 0000000..3cf3e60 --- /dev/null +++ b/tests/expectations/tag/constant_user_defined_type.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +enum E { + V, +}; + +struct S { + uint8_t field; +}; + +typedef uint8_t A; + +#define C1 (S){ .field = 0 } + +#define C2 V + +#define C3 0 diff --git a/tests/expectations/tag/constant_user_defined_type.compat.c b/tests/expectations/tag/constant_user_defined_type.compat.c new file mode 100644 index 0000000..3cf3e60 --- /dev/null +++ b/tests/expectations/tag/constant_user_defined_type.compat.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +enum E { + V, +}; + +struct S { + uint8_t field; +}; + +typedef uint8_t A; + +#define C1 (S){ .field = 0 } + +#define C2 V + +#define C3 0 diff --git a/tests/rust/constant_user_defined_type.rs b/tests/rust/constant_user_defined_type.rs new file mode 100644 index 0000000..cffe817 --- /dev/null +++ b/tests/rust/constant_user_defined_type.rs @@ -0,0 +1,17 @@ +#[repr(C)] +pub struct S { + field: u8, +} + +/// cbindgen:enum-class=false +#[repr(C)] +pub enum E { + V, +} +use E::*; + +pub type A = u8; + +pub const C1: S = S { field: 0 }; +pub const C2: E = V; +pub const C3: A = 0;