Ideally we'd just do this when we need it, but the ostream derivation
will be controlled by both global config and per-structure config, so
it's hard to know exactly when we need it and when we don't.
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;
This option allows specifying that a C++ enum should be emitted with
plain `enum` rather than `enum class`. It's true that `enum class` should
generally be preferred, but sometimes there's existing code which is
already using plain `enum`, and porting that code to Rust becomes easier when
`cbindgen` can emit plain `enum`.
This option can be overridden on a per-enum basis using a `cbindgen:` annotation.
It defaults to true for two reasons:
* Backward compatibility.
* `enum class` is probably actually what you want, in general.
Using operator= is not quite sound in presence of destructors and operator
overloading.
It's perfectly fine to assume that the left-hand-side of an operator= expression
is valid memory, however we're using uninitialized memory here, that may not be
the case.
Use placement new to properly construct tagged unions. I don't need this with
any urgency, but it's the right thing to do in presence of complex types, and
the current code seems a bomb waiting to explode :)