Skip to content

Commit

Permalink
struct literal defines by condition
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowone committed Oct 29, 2024
1 parent c52f16f commit 22a4c6f
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 9 deletions.
47 changes: 38 additions & 9 deletions src/bindgen/language_backend/clike.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,18 @@ impl LanguageBackend for CLikeLanguageBackend<'_> {
write!(out, "{}", export_name);
}

macro_rules! write_field_name {
($out:ident, $key:ident) => {
if self.config.language == Language::Cxx {
// TODO: Some C++ versions (c++20?) now support designated
// initializers, consider generating them.
write!($out, "/* .{} = */ ", $key);
} else {
write!($out, ".{} = ", $key);
}
};
}

write!(out, "{{");
if is_constexpr {
out.push_tab();
Expand All @@ -912,12 +924,11 @@ 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();

// TODO: Some C++ versions (c++20?) now support designated
// initializers, consider generating them.
write!(out, "/* .{} = */ ", ordered_key);
write_field_name!(out, ordered_key);
self.write_literal(out, &lit.value);
if i + 1 != ordered_fields.len() {
write!(out, ",");
Expand All @@ -930,14 +941,14 @@ impl LanguageBackend for CLikeLanguageBackend<'_> {
write!(out, ", ");
}

if self.config.language == Language::Cxx {
// TODO: Some C++ versions (c++20?) now support designated
// initializers, consider generating them.
write!(out, "/* .{} = */ ", ordered_key);
if condition.is_some() {
write!(out, "__{export_name}_{ordered_key}(");
self.write_literal(out, &lit.value);
write!(out, ")")
} else {
write!(out, ".{} = ", ordered_key);
write_field_name!(out, ordered_key);
self.write_literal(out, &lit.value);
}
self.write_literal(out, &lit.value);
}
}
}
Expand All @@ -948,6 +959,24 @@ impl LanguageBackend for CLikeLanguageBackend<'_> {
write!(out, " ");
}
write!(out, "}}");

if self.config.language == Language::C {
for ordered_key in ordered_fields.iter() {
if let Some(lit) = fields.get(ordered_key) {
if let Some(condition) = lit.cfg.to_condition(self.config) {
out.new_line();
condition.write_before(self.config, out);
let define = format!("#define __{export_name}_{ordered_key}(v)");
write!(out, "{define} ");
write_field_name!(out, ordered_key);
write!(out, "(v)");
write!(out, "\n#else\n");
write!(out, "{define}");
condition.write_after(self.config, out);
}
}
}
}
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ typedef struct {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ typedef struct {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct {
int32_t x;
Expand Down
6 changes: 6 additions & 0 deletions tests/expectations/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ struct ConditionalField {
#endif
;
};
constexpr static const ConditionalField ConditionalField_ZERO = ConditionalField{
/* .field = */ 0
};
constexpr static const ConditionalField ConditionalField_ONE = ConditionalField{
/* .field = */ 1
};

struct Normal {
int32_t x;
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/cfg.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ cdef extern from *:

ctypedef struct ConditionalField:
int32_t field;
const ConditionalField ConditionalField_ZERO # = <ConditionalField>{ 0 }
const ConditionalField ConditionalField_ONE # = <ConditionalField>{ 1 }

ctypedef struct Normal:
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_both.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ typedef struct ConditionalField {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct Normal {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_both.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ typedef struct ConditionalField {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct Normal {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ struct ConditionalField {
#endif
;
};
#define ConditionalField_ZERO (ConditionalField){ __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif

struct Normal {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_tag.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ struct ConditionalField {
#endif
;
};
#define ConditionalField_ZERO (ConditionalField){ __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) .field = (v)
#else
#define __ConditionalField_field(v)
#endif

struct Normal {
int32_t x;
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/cfg_tag.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ cdef extern from *:

cdef struct ConditionalField:
int32_t field;
const ConditionalField ConditionalField_ZERO # = <ConditionalField>{ 0 }
const ConditionalField ConditionalField_ONE # = <ConditionalField>{ 1 }

cdef struct Normal:
int32_t x;
Expand Down
11 changes: 11 additions & 0 deletions tests/rust/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 22a4c6f

Please sign in to comment.