Skip to content

Commit df0167b

Browse files
committed
Do not emit enum TagName tag when a sized representation is present.
This affected cases where the style was set to `Stle::Tag`. In enumerations, do not emut the tag type name with an `enum` prefix. C treats the `enum` type as an `int` even if the representation should be something else. Here's an example non-C-like-enumeration: #[repr(C, u8)] enum P { P1(u8), P2(u8, u8), P3(u8, u8, u8), } Without this patch, this is what's generated: enum P_Tag { P1, P2, P3, }; typedef uint8_t P_Tag; typedef struct { uint8_t _0; } P1_Body; typedef struct { uint8_t _0; uint8_t _1; } P2_Body; typedef struct { uint8_t _0; uint8_t _1; uint8_t _2; } P3_Body; typedef struct { enum P_Tag tag; union { P1_Body p1; P2_Body p2; P3_Body p3; }; } P; Rust expects the size of the type to be 4 (one for the discriminant, and 3 for the widest alternative. C, however, treats the `enum P_Tag tag` field as an `int` rather than a `uint8_t`. This puts the size (with padding) of of `P` to 8 bytes instead of 4. When passing this type between Rust and C, they will disagree on the size. After the patch is applied, the `P` struct is properly defined: typedef struct { P_Tag tag; union { P1_Body p1; P2_Body p2; P3_Body p3; }; } P;
1 parent bac063e commit df0167b

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

src/bindgen/ir/enumeration.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,8 @@ impl Source for Enum {
682682
out.open_brace();
683683
}
684684

685-
if config.language == Language::C && !config.style.generate_typedef() {
685+
if config.language == Language::C && !size.is_some() && !config.style.generate_typedef()
686+
{
686687
out.write("enum ");
687688
}
688689

0 commit comments

Comments
 (0)