Skip to content

Commit

Permalink
Generate flexible array members the c99 way instead of the GNU way
Browse files Browse the repository at this point in the history
There a re three ways to express flexible array members:

1. char fam[0];
2. char fam[1];
3. char fam[];

3. is the only standard way (in c99, but supported in c++ as an
extension), the other two are GNU syntax (still supported in clang
though).

Let's generate the standard syntax by default, while leaving it possible to
use 1. through struct.gnu_flexible_array_members

Cython only supports the 1. mode.
  • Loading branch information
serge-sans-paille committed Aug 15, 2024
1 parent 3ed9434 commit 05cde18
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 12 deletions.
13 changes: 11 additions & 2 deletions src/bindgen/cdecl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ impl CDecl {
}

// Write the right part of declarators after the identifier
let mut iter = self.declarators.iter();
let mut iter = self.declarators.iter().peekable();
let mut last_was_pointer = false;

#[allow(clippy::while_let_on_iterator)]
Expand All @@ -286,7 +286,16 @@ impl CDecl {
if last_was_pointer {
out.write(")");
}
write!(out, "[{}]", constant);

let is_fam = constant == "0" && iter.peek().is_none();
if is_fam
&& !config.structure.gnu_flexible_array_members
&& config.language != Language::Cython
{
write!(out, "[]");
} else {
write!(out, "[{}]", constant);
}

last_was_pointer = false;
}
Expand Down
2 changes: 2 additions & 0 deletions src/bindgen/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,8 @@ pub struct StructConfig {
pub deprecated: Option<String>,
/// The way to annotation this function as #[deprecated] with notes
pub deprecated_with_note: Option<String>,
/// The way we represent flexible array members, either GNU style or c99 style
pub gnu_flexible_array_members: bool,
}

impl StructConfig {
Expand Down
12 changes: 11 additions & 1 deletion tests/expectations/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,14 @@ typedef struct {
float y;
} TupleNamed;

void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
typedef struct {
int32_t x;
int8_t y[];
} WithFlexibleArrayMember;

void root(Opaque *a,
Normal b,
NormalWithZST c,
TupleRenamed d,
TupleNamed e,
WithFlexibleArrayMember f);
12 changes: 11 additions & 1 deletion tests/expectations/struct.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,21 @@ typedef struct {
float y;
} TupleNamed;

typedef struct {
int32_t x;
int8_t y[];
} WithFlexibleArrayMember;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
void root(Opaque *a,
Normal b,
NormalWithZST c,
TupleRenamed d,
TupleNamed e,
WithFlexibleArrayMember f);

#ifdef __cplusplus
} // extern "C"
Expand Down
12 changes: 11 additions & 1 deletion tests/expectations/struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,18 @@ struct TupleNamed {
float y;
};

struct WithFlexibleArrayMember {
int32_t x;
int8_t y[];
};

extern "C" {

void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
void root(Opaque *a,
Normal b,
NormalWithZST c,
TupleRenamed d,
TupleNamed e,
WithFlexibleArrayMember f);

} // extern "C"
11 changes: 10 additions & 1 deletion tests/expectations/struct.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ cdef extern from *:
int32_t x;
float y;

void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
ctypedef struct WithFlexibleArrayMember:
int32_t x;
int8_t y[0];

void root(Opaque *a,
Normal b,
NormalWithZST c,
TupleRenamed d,
TupleNamed e,
WithFlexibleArrayMember f);
8 changes: 7 additions & 1 deletion tests/expectations/struct_both.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ typedef struct TupleNamed {
float y;
} TupleNamed;

typedef struct WithFlexibleArrayMember {
int32_t x;
int8_t y[];
} WithFlexibleArrayMember;

void root(struct Opaque *a,
struct Normal b,
struct NormalWithZST c,
struct TupleRenamed d,
struct TupleNamed e);
struct TupleNamed e,
struct WithFlexibleArrayMember f);
8 changes: 7 additions & 1 deletion tests/expectations/struct_both.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ typedef struct TupleNamed {
float y;
} TupleNamed;

typedef struct WithFlexibleArrayMember {
int32_t x;
int8_t y[];
} WithFlexibleArrayMember;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
Expand All @@ -33,7 +38,8 @@ void root(struct Opaque *a,
struct Normal b,
struct NormalWithZST c,
struct TupleRenamed d,
struct TupleNamed e);
struct TupleNamed e,
struct WithFlexibleArrayMember f);

#ifdef __cplusplus
} // extern "C"
Expand Down
8 changes: 7 additions & 1 deletion tests/expectations/struct_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ struct TupleNamed {
float y;
};

struct WithFlexibleArrayMember {
int32_t x;
int8_t y[];
};

void root(struct Opaque *a,
struct Normal b,
struct NormalWithZST c,
struct TupleRenamed d,
struct TupleNamed e);
struct TupleNamed e,
struct WithFlexibleArrayMember f);
8 changes: 7 additions & 1 deletion tests/expectations/struct_tag.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ struct TupleNamed {
float y;
};

struct WithFlexibleArrayMember {
int32_t x;
int8_t y[];
};

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
Expand All @@ -33,7 +38,8 @@ void root(struct Opaque *a,
struct Normal b,
struct NormalWithZST c,
struct TupleRenamed d,
struct TupleNamed e);
struct TupleNamed e,
struct WithFlexibleArrayMember f);

#ifdef __cplusplus
} // extern "C"
Expand Down
11 changes: 10 additions & 1 deletion tests/expectations/struct_tag.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ cdef extern from *:
int32_t x;
float y;

void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
cdef struct WithFlexibleArrayMember:
int32_t x;
int8_t y[0];

void root(Opaque *a,
Normal b,
NormalWithZST c,
TupleRenamed d,
TupleNamed e,
WithFlexibleArrayMember f);
9 changes: 8 additions & 1 deletion tests/rust/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@ struct TupleRenamed(i32, f32);
#[repr(C)]
struct TupleNamed(i32, f32);

#[repr(C)]
struct WithFlexibleArrayMember {
x: i32,
y: [i8; 0],
}

#[no_mangle]
pub extern "C" fn root(
a: *mut Opaque,
b: Normal,
c: NormalWithZST,
d: TupleRenamed,
e: TupleNamed
e: TupleNamed,
f: WithFlexibleArrayMember,
) { }

0 comments on commit 05cde18

Please sign in to comment.