This is needed when running tests with clang/clang++, as some of the tests have
errors that clang reports which gcc does not such as unused static const
variables.
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 will be useful to add static assertion to some tests like #463 wants to do.
For example, in the case of the test for #463, the test would need something
like:
trailer = """
#include <assert.h>
#if defined(CBINDGEN_STYLE_TAG) && !defined(__cplusplus)
static_assert(sizeof(struct P) == 4, "unexpected size for P");
#else
static_assert(sizeof(P) == 4, "unexpected size for P");
#endif
"""
As more of these tests are added it may be worth just adding a helper header
like this to avoid some duplication:
#include <assert.h>
#if defined(CBINDGEN_STYLE_TAG) && !defined(__cplusplus)
#define CBINDGEN_STRUCT(name) struct name
#else
#define CBINDGEN_STRUCT(name) name
#endif
And so on, so the previous configuration would become just:
trailer = """
#include "testing-helpers.h" // Or whatever
static_assert(sizeof(CBINDGEN_STRUCT(P)) == 4, "unexpected size for P");
"""
That may or may not be overkill to do as part of #463.
This adds `-Wall` and `-Werror` to the C and C++ compiler flags. It
also adds `-Wno-attributes` to disable warnings about unrecognized
attributes. This is needed because the `swift_name` test relies on
`__attribute__((swift_name(some_name)))` attribute.
Shifting a literal (which is an int when a suffix is not present)
generates a warning because the only possible result is 0, and the
programmer probably didn't intend to do that.
Change the shift to a value less than 32. The test exhibiting the
warning wasn't aiming to test integer promotion rules, so I've opted
to change the constant.
With lockfile v2 a version is not required for dependencies if the lock
file only contains a single entry for a specified crate. However, without
a version present, at a later stage, a dependant crate will not be found
in the metadata cache which causes the dependency to be ignored completely.
This commit tries to infer the version of dependant crates when the
version specifier is missing from the contents of the lockfile.
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.
And recommend its usage if copy-constructors are being generated, as otherwise
C++ in its whole glory would do a bitwise copy, which is not really what you
want if you have constructors / destructors around.
The tests are very straightforward, and effecitvely are just ensuring
that the formatting works correctly and is included in all of the
important cases.
It's also very important to ensure we do not generate laid-out structs
for layouts which we cannot reasonably represent in C (such as in cases
where we weren't told what annotation to use for packed and
specifically-aligned structures). Thus, add some tests to verify that
this is the case.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>