From 2ed778c1d31346f27b93d53a6cb98b2217788afe Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 11 Aug 2024 00:36:05 +0900 Subject: [PATCH] conditional fields of constexpr literal structs --- src/bindgen/language_backend/clike.rs | 6 +++--- tests/expectations/cfg.c | 2 ++ tests/expectations/cfg.compat.c | 2 ++ tests/expectations/cfg.cpp | 10 ++++++++++ tests/expectations/cfg.pyx | 2 ++ tests/expectations/cfg_both.c | 2 ++ tests/expectations/cfg_both.compat.c | 2 ++ tests/expectations/cfg_tag.c | 2 ++ tests/expectations/cfg_tag.compat.c | 2 ++ tests/expectations/cfg_tag.pyx | 2 ++ tests/rust/cfg.rs | 11 +++++++++++ 11 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/bindgen/language_backend/clike.rs b/src/bindgen/language_backend/clike.rs index 3830b02a..3968193e 100644 --- a/src/bindgen/language_backend/clike.rs +++ b/src/bindgen/language_backend/clike.rs @@ -912,19 +912,19 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { let ordered_fields = out.bindings().struct_field_names(path); for (i, ordered_key) in ordered_fields.iter().enumerate() { if let Some(lit) = fields.get(ordered_key) { + let condition = lit.cfg.to_condition(self.config); if is_constexpr { out.new_line(); + condition.write_before(self.config, out); // TODO: Some C++ versions (c++20?) now support designated // initializers, consider generating them. write!(out, "/* .{} = */ ", ordered_key); self.write_literal(out, &lit.value); if i + 1 != ordered_fields.len() { write!(out, ","); - if !is_constexpr { - write!(out, " "); - } } + condition.write_after(self.config, out); } else { if i > 0 { write!(out, ", "); diff --git a/tests/expectations/cfg.c b/tests/expectations/cfg.c index 9285f300..800b518f 100644 --- a/tests/expectations/cfg.c +++ b/tests/expectations/cfg.c @@ -77,6 +77,8 @@ typedef struct { #endif ; } ConditionalField; +#define ConditionalField_ZERO (ConditionalField){ .field = 0 } +#define ConditionalField_ONE (ConditionalField){ .field = 1 } typedef struct { int32_t x; diff --git a/tests/expectations/cfg.compat.c b/tests/expectations/cfg.compat.c index 053c4052..6a457435 100644 --- a/tests/expectations/cfg.compat.c +++ b/tests/expectations/cfg.compat.c @@ -95,6 +95,8 @@ typedef struct { #endif ; } ConditionalField; +#define ConditionalField_ZERO (ConditionalField){ .field = 0 } +#define ConditionalField_ONE (ConditionalField){ .field = 1 } typedef struct { int32_t x; diff --git a/tests/expectations/cfg.cpp b/tests/expectations/cfg.cpp index d7b6250d..1eed9afd 100644 --- a/tests/expectations/cfg.cpp +++ b/tests/expectations/cfg.cpp @@ -201,6 +201,16 @@ struct ConditionalField { #endif ; }; +constexpr static const ConditionalField ConditionalField_ZERO = ConditionalField{ +#if defined(X11) + /* .field = */ 0 +#endif +}; +constexpr static const ConditionalField ConditionalField_ONE = ConditionalField{ +#if defined(X11) + /* .field = */ 1 +#endif +}; struct Normal { int32_t x; diff --git a/tests/expectations/cfg.pyx b/tests/expectations/cfg.pyx index e23fc703..803fd7a7 100644 --- a/tests/expectations/cfg.pyx +++ b/tests/expectations/cfg.pyx @@ -57,6 +57,8 @@ cdef extern from *: ctypedef struct ConditionalField: int32_t field; + const ConditionalField ConditionalField_ZERO # = { 0 } + const ConditionalField ConditionalField_ONE # = { 1 } ctypedef struct Normal: int32_t x; diff --git a/tests/expectations/cfg_both.c b/tests/expectations/cfg_both.c index 510e34e8..55fcc894 100644 --- a/tests/expectations/cfg_both.c +++ b/tests/expectations/cfg_both.c @@ -77,6 +77,8 @@ typedef struct ConditionalField { #endif ; } ConditionalField; +#define ConditionalField_ZERO (ConditionalField){ .field = 0 } +#define ConditionalField_ONE (ConditionalField){ .field = 1 } typedef struct Normal { int32_t x; diff --git a/tests/expectations/cfg_both.compat.c b/tests/expectations/cfg_both.compat.c index 2377824e..000b03d4 100644 --- a/tests/expectations/cfg_both.compat.c +++ b/tests/expectations/cfg_both.compat.c @@ -95,6 +95,8 @@ typedef struct ConditionalField { #endif ; } ConditionalField; +#define ConditionalField_ZERO (ConditionalField){ .field = 0 } +#define ConditionalField_ONE (ConditionalField){ .field = 1 } typedef struct Normal { int32_t x; diff --git a/tests/expectations/cfg_tag.c b/tests/expectations/cfg_tag.c index 8cc88538..f9cad7b5 100644 --- a/tests/expectations/cfg_tag.c +++ b/tests/expectations/cfg_tag.c @@ -77,6 +77,8 @@ struct ConditionalField { #endif ; }; +#define ConditionalField_ZERO (ConditionalField){ .field = 0 } +#define ConditionalField_ONE (ConditionalField){ .field = 1 } struct Normal { int32_t x; diff --git a/tests/expectations/cfg_tag.compat.c b/tests/expectations/cfg_tag.compat.c index ec976353..cfe66ffd 100644 --- a/tests/expectations/cfg_tag.compat.c +++ b/tests/expectations/cfg_tag.compat.c @@ -95,6 +95,8 @@ struct ConditionalField { #endif ; }; +#define ConditionalField_ZERO (ConditionalField){ .field = 0 } +#define ConditionalField_ONE (ConditionalField){ .field = 1 } struct Normal { int32_t x; diff --git a/tests/expectations/cfg_tag.pyx b/tests/expectations/cfg_tag.pyx index e508bb30..6a0d44d7 100644 --- a/tests/expectations/cfg_tag.pyx +++ b/tests/expectations/cfg_tag.pyx @@ -57,6 +57,8 @@ cdef extern from *: cdef struct ConditionalField: int32_t field; + const ConditionalField ConditionalField_ZERO # = { 0 } + const ConditionalField ConditionalField_ONE # = { 1 } cdef struct Normal: int32_t x; diff --git a/tests/rust/cfg.rs b/tests/rust/cfg.rs index 70893609..0efe3546 100644 --- a/tests/rust/cfg.rs +++ b/tests/rust/cfg.rs @@ -49,6 +49,17 @@ struct ConditionalField { field: i32, } +impl ConditionalField { + pub const ZERO: Self = Self { + #[cfg(x11)] + field: 0, + }; + pub const ONE: Self = Self { + #[cfg(x11)] + field: 1, + }; +} + #[cfg(all(unix, x11))] #[no_mangle] pub extern "C" fn root(a: FooHandle, c: C)