Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 38 additions & 11 deletions src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,15 +680,20 @@ impl Enum {
}
write!(out, " {tag_name}");

if config.cpp_compatible_c() {
out.new_line();
out.write("#ifdef __cplusplus");
out.new_line();
write!(out, " : {prim}");
out.new_line();
out.write("#endif // __cplusplus");
out.new_line();
}
// Emit typed enum syntax (valid in C23 or later or C++)
let cond = if config.cpp_compatible_c() {
"defined(__cplusplus) || __STDC_VERSION__ >= 202311L"
} else {
"__STDC_VERSION__ >= 202311L"
};

out.new_line();
write!(out, "#if {cond}");
out.new_line();
write!(out, " : {prim}");
out.new_line();
write!(out, "#endif // {cond}");
out.new_line();
} else {
if config.style.generate_typedef() {
out.write("typedef ");
Expand Down Expand Up @@ -759,17 +764,39 @@ impl Enum {
}

// Emit typedef specifying the tag enum's size if necessary.
// In C++ enums can "inherit" from numeric types (`enum E: uint8_t { ... }`),
// but in C `typedef uint8_t E` is the only way to give a fixed size to `E`.
// In C++ or C23 enums can "inherit" from numeric types (`enum E: uint8_t { ... }`),
// but in older versions of C `typedef uint8_t E` is the only way to give a fixed size to `E`.
if let Some(prim) = size {
if config.cpp_compatible_c() {
out.new_line_if_not_start();
out.write("#ifndef __cplusplus");
}

if config.language != Language::Cxx {
if config.language == Language::C {
out.new_line();
out.write("#if __STDC_VERSION__ >= 202311L");

out.new_line();
write!(
out,
"{} enum {} {};",
config.language.typedef(),
tag_name,
tag_name
);

out.new_line();
out.write("#else");
}

out.new_line();
write!(out, "{} {} {};", config.language.typedef(), prim, tag_name);

if config.language == Language::C {
out.new_line();
out.write("#endif // __STDC_VERSION__ >= 202311L");
}
}

if config.cpp_compatible_c() {
Expand Down
10 changes: 9 additions & 1 deletion tests/expectations/alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
#include <stdint.h>
#include <stdlib.h>

enum Status {
enum Status
#if __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __STDC_VERSION__ >= 202311L
{
Ok,
Err,
};
#if __STDC_VERSION__ >= 202311L
typedef enum Status Status;
#else
typedef uint32_t Status;
#endif // __STDC_VERSION__ >= 202311L

typedef struct {
int32_t a;
Expand Down
8 changes: 6 additions & 2 deletions tests/expectations/alias.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
#include <stdlib.h>

enum Status
#ifdef __cplusplus
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __cplusplus
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
{
Ok,
Err,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum Status Status;
#else
typedef uint32_t Status;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

typedef struct {
Expand Down
10 changes: 9 additions & 1 deletion tests/expectations/alias_both.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
#include <stdint.h>
#include <stdlib.h>

enum Status {
enum Status
#if __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __STDC_VERSION__ >= 202311L
{
Ok,
Err,
};
#if __STDC_VERSION__ >= 202311L
typedef enum Status Status;
#else
typedef uint32_t Status;
#endif // __STDC_VERSION__ >= 202311L

typedef struct Dep {
int32_t a;
Expand Down
8 changes: 6 additions & 2 deletions tests/expectations/alias_both.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
#include <stdlib.h>

enum Status
#ifdef __cplusplus
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __cplusplus
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
{
Ok,
Err,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum Status Status;
#else
typedef uint32_t Status;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

typedef struct Dep {
Expand Down
10 changes: 9 additions & 1 deletion tests/expectations/alias_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
#include <stdint.h>
#include <stdlib.h>

enum Status {
enum Status
#if __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __STDC_VERSION__ >= 202311L
{
Ok,
Err,
};
#if __STDC_VERSION__ >= 202311L
typedef enum Status Status;
#else
typedef uint32_t Status;
#endif // __STDC_VERSION__ >= 202311L

struct Dep {
int32_t a;
Expand Down
8 changes: 6 additions & 2 deletions tests/expectations/alias_tag.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
#include <stdlib.h>

enum Status
#ifdef __cplusplus
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __cplusplus
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
{
Ok,
Err,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum Status Status;
#else
typedef uint32_t Status;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

struct Dep {
Expand Down
30 changes: 27 additions & 3 deletions tests/expectations/annotation.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
#include <stdint.h>
#include <stdlib.h>

enum C {
enum C
#if __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __STDC_VERSION__ >= 202311L
{
X = 2,
Y,
};
#if __STDC_VERSION__ >= 202311L
typedef enum C C;
#else
typedef uint32_t C;
#endif // __STDC_VERSION__ >= 202311L

typedef struct {
int32_t m0;
Expand All @@ -18,12 +26,20 @@ typedef struct {
float y;
} B;

enum F_Tag {
enum F_Tag
#if __STDC_VERSION__ >= 202311L
: uint8_t
#endif // __STDC_VERSION__ >= 202311L
{
Foo,
Bar,
Baz,
};
#if __STDC_VERSION__ >= 202311L
typedef enum F_Tag F_Tag;
#else
typedef uint8_t F_Tag;
#endif // __STDC_VERSION__ >= 202311L

typedef struct {
F_Tag tag;
Expand All @@ -40,12 +56,20 @@ typedef union {
Bar_Body bar;
} F;

enum H_Tag {
enum H_Tag
#if __STDC_VERSION__ >= 202311L
: uint8_t
#endif // __STDC_VERSION__ >= 202311L
{
Hello,
There,
Everyone,
};
#if __STDC_VERSION__ >= 202311L
typedef enum H_Tag H_Tag;
#else
typedef uint8_t H_Tag;
#endif // __STDC_VERSION__ >= 202311L

typedef struct {
uint8_t x;
Expand Down
24 changes: 18 additions & 6 deletions tests/expectations/annotation.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
#include <stdlib.h>

enum C
#ifdef __cplusplus
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __cplusplus
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
{
X = 2,
Y,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum C C;
#else
typedef uint32_t C;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

typedef struct {
Expand All @@ -25,16 +29,20 @@ typedef struct {
} B;

enum F_Tag
#ifdef __cplusplus
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
: uint8_t
#endif // __cplusplus
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
{
Foo,
Bar,
Baz,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum F_Tag F_Tag;
#else
typedef uint8_t F_Tag;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

typedef struct {
Expand All @@ -53,16 +61,20 @@ typedef union {
} F;

enum H_Tag
#ifdef __cplusplus
#if defined(__cplusplus) || __STDC_VERSION__ >= 202311L
: uint8_t
#endif // __cplusplus
#endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L
{
Hello,
There,
Everyone,
};
#ifndef __cplusplus
#if __STDC_VERSION__ >= 202311L
typedef enum H_Tag H_Tag;
#else
typedef uint8_t H_Tag;
#endif // __STDC_VERSION__ >= 202311L
#endif // __cplusplus

typedef struct {
Expand Down
30 changes: 27 additions & 3 deletions tests/expectations/annotation_both.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
#include <stdint.h>
#include <stdlib.h>

enum C {
enum C
#if __STDC_VERSION__ >= 202311L
: uint32_t
#endif // __STDC_VERSION__ >= 202311L
{
X = 2,
Y,
};
#if __STDC_VERSION__ >= 202311L
typedef enum C C;
#else
typedef uint32_t C;
#endif // __STDC_VERSION__ >= 202311L

typedef struct A {
int32_t m0;
Expand All @@ -18,12 +26,20 @@ typedef struct B {
float y;
} B;

enum F_Tag {
enum F_Tag
#if __STDC_VERSION__ >= 202311L
: uint8_t
#endif // __STDC_VERSION__ >= 202311L
{
Foo,
Bar,
Baz,
};
#if __STDC_VERSION__ >= 202311L
typedef enum F_Tag F_Tag;
#else
typedef uint8_t F_Tag;
#endif // __STDC_VERSION__ >= 202311L

typedef struct Bar_Body {
F_Tag tag;
Expand All @@ -40,12 +56,20 @@ typedef union F {
Bar_Body bar;
} F;

enum H_Tag {
enum H_Tag
#if __STDC_VERSION__ >= 202311L
: uint8_t
#endif // __STDC_VERSION__ >= 202311L
{
Hello,
There,
Everyone,
};
#if __STDC_VERSION__ >= 202311L
typedef enum H_Tag H_Tag;
#else
typedef uint8_t H_Tag;
#endif // __STDC_VERSION__ >= 202311L

typedef struct There_Body {
uint8_t x;
Expand Down
Loading