From 5b418d968c57c4d5b7030748a2593539a140d02e Mon Sep 17 00:00:00 2001 From: kavoor Date: Wed, 13 Apr 2022 01:34:53 -0700 Subject: [PATCH] Support rename rule for union body members. Closes #751. --- src/bindgen/config.rs | 5 +++++ src/bindgen/ir/enumeration.rs | 9 +++++++-- tests/expectations/enum.both.c | 24 +++++++++++++++++++++++- tests/expectations/enum.both.compat.c | 24 +++++++++++++++++++++++- tests/expectations/enum.c | 24 +++++++++++++++++++++++- tests/expectations/enum.compat.c | 24 +++++++++++++++++++++++- tests/expectations/enum.cpp | 26 +++++++++++++++++++++++++- tests/expectations/enum.pyx | 17 ++++++++++++++++- tests/expectations/enum.tag.c | 24 +++++++++++++++++++++++- tests/expectations/enum.tag.compat.c | 24 +++++++++++++++++++++++- tests/expectations/enum.tag.pyx | 17 ++++++++++++++++- tests/rust/enum.rs | 9 +++++++++ 12 files changed, 216 insertions(+), 11 deletions(-) diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index 3560bb2c9..d0dbf2205 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -559,6 +559,10 @@ impl StructConfig { pub struct EnumConfig { /// The rename rule to apply to the name of enum variants pub rename_variants: RenameRule, + /// The rename rule to apply to the names of the union fields in C/C++ + /// generated from the Rust enum. Applied before rename_variants + /// rename rule. Defaults to SnakeCase. + pub rename_variant_name_fields: RenameRule, /// Whether to add a `Sentinel` value at the end of every enum /// This is useful in Gecko for IPC serialization pub add_sentinel: bool, @@ -600,6 +604,7 @@ impl Default for EnumConfig { fn default() -> EnumConfig { EnumConfig { rename_variants: RenameRule::None, + rename_variant_name_fields: RenameRule::SnakeCase, add_sentinel: false, prefix_with_name: false, derive_helper_methods: false, diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index aa19bff7b..413ba7223 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -149,11 +149,16 @@ impl EnumVariant { if let Some(b) = enum_annotations.bool("derive-ostream") { annotations.add_default("derive-ostream", AnnotationValue::Bool(b)); } + + let body_rule = enum_annotations + .parse_atom::("rename-variant-name-fields") + .unwrap_or(config.enumeration.rename_variant_name_fields); + let body = match variant.fields { syn::Fields::Unit => VariantBody::Empty(annotations), syn::Fields::Named(ref fields) => { let path = Path::new(format!("{}_Body", variant.ident)); - let name = RenameRule::SnakeCase + let name = body_rule .apply( &variant.ident.unraw().to_string(), IdentifierType::StructMember, @@ -179,7 +184,7 @@ impl EnumVariant { } syn::Fields::Unnamed(ref fields) => { let path = Path::new(format!("{}_Body", variant.ident)); - let name = RenameRule::SnakeCase + let name = body_rule .apply( &variant.ident.unraw().to_string(), IdentifierType::StructMember, diff --git a/tests/expectations/enum.both.c b/tests/expectations/enum.both.c index 3c22fd5c9..a0f88c13e 100644 --- a/tests/expectations/enum.both.c +++ b/tests/expectations/enum.both.c @@ -204,6 +204,27 @@ typedef struct Q { }; } Q; +typedef enum R_Tag { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct IRBar_Body { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct R { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + void root(struct Opaque *opaque, A a, B b, @@ -221,7 +242,8 @@ void root(struct Opaque *opaque, enum N n, O o, struct P p, - struct Q q); + struct Q q, + struct R r); #if 0 ''' ' diff --git a/tests/expectations/enum.both.compat.c b/tests/expectations/enum.both.compat.c index b8ef28422..88d59a700 100644 --- a/tests/expectations/enum.both.compat.c +++ b/tests/expectations/enum.both.compat.c @@ -270,6 +270,27 @@ typedef struct Q { }; } Q; +typedef enum R_Tag { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct IRBar_Body { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct R { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -291,7 +312,8 @@ void root(struct Opaque *opaque, enum N n, O o, struct P p, - struct Q q); + struct Q q, + struct R r); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/enum.c b/tests/expectations/enum.c index d3d6b6f38..0562a56a6 100644 --- a/tests/expectations/enum.c +++ b/tests/expectations/enum.c @@ -204,6 +204,27 @@ typedef struct { }; } Q; +typedef enum { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + void root(Opaque *opaque, A a, B b, @@ -221,7 +242,8 @@ void root(Opaque *opaque, N n, O o, P p, - Q q); + Q q, + R r); #if 0 ''' ' diff --git a/tests/expectations/enum.compat.c b/tests/expectations/enum.compat.c index 4de1cd3bb..3dc7c331d 100644 --- a/tests/expectations/enum.compat.c +++ b/tests/expectations/enum.compat.c @@ -270,6 +270,27 @@ typedef struct { }; } Q; +typedef enum { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -291,7 +312,8 @@ void root(Opaque *opaque, N n, O o, P p, - Q q); + Q q, + R r); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/enum.cpp b/tests/expectations/enum.cpp index 4b927532b..2f16218a9 100644 --- a/tests/expectations/enum.cpp +++ b/tests/expectations/enum.cpp @@ -208,6 +208,29 @@ struct Q { }; }; +struct R { + enum class Tag { + IRFoo, + IRBar, + IRBaz, + }; + + struct IRFoo_Body { + int16_t _0; + }; + + struct IRBar_Body { + uint8_t x; + int16_t y; + }; + + Tag tag; + union { + IRFoo_Body IRFoo; + IRBar_Body IRBar; + }; +}; + extern "C" { void root(Opaque *opaque, @@ -227,7 +250,8 @@ void root(Opaque *opaque, N n, O o, P p, - Q q); + Q q, + R r); } // extern "C" diff --git a/tests/expectations/enum.pyx b/tests/expectations/enum.pyx index 3248c4d8b..03570f2c3 100644 --- a/tests/expectations/enum.pyx +++ b/tests/expectations/enum.pyx @@ -165,6 +165,20 @@ cdef extern from *: uint32_t *ok; uint32_t err; + ctypedef enum R_Tag: + IRFoo, + IRBar, + IRBaz, + + ctypedef struct IRBar_Body: + uint8_t x; + int16_t y; + + ctypedef struct R: + R_Tag tag; + int16_t IRFoo; + IRBar_Body IRBar; + void root(Opaque *opaque, A a, B b, @@ -182,7 +196,8 @@ cdef extern from *: N n, O o, P p, - Q q); + Q q, + R r); #if 0 ''' ' diff --git a/tests/expectations/enum.tag.c b/tests/expectations/enum.tag.c index 01a6aa83e..a7f104688 100644 --- a/tests/expectations/enum.tag.c +++ b/tests/expectations/enum.tag.c @@ -204,6 +204,27 @@ struct Q { }; }; +enum R_Tag { + IRFoo, + IRBar, + IRBaz, +}; + +struct IRBar_Body { + uint8_t x; + int16_t y; +}; + +struct R { + enum R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + struct IRBar_Body IRBar; + }; +}; + void root(struct Opaque *opaque, A a, B b, @@ -221,7 +242,8 @@ void root(struct Opaque *opaque, enum N n, O o, struct P p, - struct Q q); + struct Q q, + struct R r); #if 0 ''' ' diff --git a/tests/expectations/enum.tag.compat.c b/tests/expectations/enum.tag.compat.c index f5ae9dfe8..73d64ba79 100644 --- a/tests/expectations/enum.tag.compat.c +++ b/tests/expectations/enum.tag.compat.c @@ -270,6 +270,27 @@ struct Q { }; }; +enum R_Tag { + IRFoo, + IRBar, + IRBaz, +}; + +struct IRBar_Body { + uint8_t x; + int16_t y; +}; + +struct R { + enum R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + struct IRBar_Body IRBar; + }; +}; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -291,7 +312,8 @@ void root(struct Opaque *opaque, enum N n, O o, struct P p, - struct Q q); + struct Q q, + struct R r); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/enum.tag.pyx b/tests/expectations/enum.tag.pyx index f315c4eb1..a0c9ef082 100644 --- a/tests/expectations/enum.tag.pyx +++ b/tests/expectations/enum.tag.pyx @@ -165,6 +165,20 @@ cdef extern from *: uint32_t *ok; uint32_t err; + cdef enum R_Tag: + IRFoo, + IRBar, + IRBaz, + + cdef struct IRBar_Body: + uint8_t x; + int16_t y; + + cdef struct R: + R_Tag tag; + int16_t IRFoo; + IRBar_Body IRBar; + void root(Opaque *opaque, A a, B b, @@ -182,7 +196,8 @@ cdef extern from *: N n, O o, P p, - Q q); + Q q, + R r); #if 0 ''' ' diff --git a/tests/rust/enum.rs b/tests/rust/enum.rs index 9c57100fb..19191ca7e 100644 --- a/tests/rust/enum.rs +++ b/tests/rust/enum.rs @@ -133,6 +133,14 @@ enum Q { Err(u32), } +/// cbindgen:rename-variant-name-fields=None +#[repr(C)] +enum R { + IRFoo(i16), + IRBar { x: u8, y: i16 }, + IRBaz, +} + #[no_mangle] pub extern "C" fn root( opaque: *mut Opaque, @@ -153,5 +161,6 @@ pub extern "C" fn root( o: O, p: P, q: Q, + r: R, ) { }