Skip to content

Commit 05cde18

Browse files
Generate flexible array members the c99 way instead of the GNU way
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.
1 parent 3ed9434 commit 05cde18

12 files changed

+102
-12
lines changed

src/bindgen/cdecl.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ impl CDecl {
273273
}
274274

275275
// Write the right part of declarators after the identifier
276-
let mut iter = self.declarators.iter();
276+
let mut iter = self.declarators.iter().peekable();
277277
let mut last_was_pointer = false;
278278

279279
#[allow(clippy::while_let_on_iterator)]
@@ -286,7 +286,16 @@ impl CDecl {
286286
if last_was_pointer {
287287
out.write(")");
288288
}
289-
write!(out, "[{}]", constant);
289+
290+
let is_fam = constant == "0" && iter.peek().is_none();
291+
if is_fam
292+
&& !config.structure.gnu_flexible_array_members
293+
&& config.language != Language::Cython
294+
{
295+
write!(out, "[]");
296+
} else {
297+
write!(out, "[{}]", constant);
298+
}
290299

291300
last_was_pointer = false;
292301
}

src/bindgen/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,8 @@ pub struct StructConfig {
499499
pub deprecated: Option<String>,
500500
/// The way to annotation this function as #[deprecated] with notes
501501
pub deprecated_with_note: Option<String>,
502+
/// The way we represent flexible array members, either GNU style or c99 style
503+
pub gnu_flexible_array_members: bool,
502504
}
503505

504506
impl StructConfig {

tests/expectations/struct.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,14 @@ typedef struct {
2525
float y;
2626
} TupleNamed;
2727

28-
void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
28+
typedef struct {
29+
int32_t x;
30+
int8_t y[];
31+
} WithFlexibleArrayMember;
32+
33+
void root(Opaque *a,
34+
Normal b,
35+
NormalWithZST c,
36+
TupleRenamed d,
37+
TupleNamed e,
38+
WithFlexibleArrayMember f);

tests/expectations/struct.compat.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,21 @@ typedef struct {
2525
float y;
2626
} TupleNamed;
2727

28+
typedef struct {
29+
int32_t x;
30+
int8_t y[];
31+
} WithFlexibleArrayMember;
32+
2833
#ifdef __cplusplus
2934
extern "C" {
3035
#endif // __cplusplus
3136

32-
void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
37+
void root(Opaque *a,
38+
Normal b,
39+
NormalWithZST c,
40+
TupleRenamed d,
41+
TupleNamed e,
42+
WithFlexibleArrayMember f);
3343

3444
#ifdef __cplusplus
3545
} // extern "C"

tests/expectations/struct.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,18 @@ struct TupleNamed {
2626
float y;
2727
};
2828

29+
struct WithFlexibleArrayMember {
30+
int32_t x;
31+
int8_t y[];
32+
};
33+
2934
extern "C" {
3035

31-
void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
36+
void root(Opaque *a,
37+
Normal b,
38+
NormalWithZST c,
39+
TupleRenamed d,
40+
TupleNamed e,
41+
WithFlexibleArrayMember f);
3242

3343
} // extern "C"

tests/expectations/struct.pyx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,13 @@ cdef extern from *:
2525
int32_t x;
2626
float y;
2727

28-
void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
28+
ctypedef struct WithFlexibleArrayMember:
29+
int32_t x;
30+
int8_t y[0];
31+
32+
void root(Opaque *a,
33+
Normal b,
34+
NormalWithZST c,
35+
TupleRenamed d,
36+
TupleNamed e,
37+
WithFlexibleArrayMember f);

tests/expectations/struct_both.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@ typedef struct TupleNamed {
2525
float y;
2626
} TupleNamed;
2727

28+
typedef struct WithFlexibleArrayMember {
29+
int32_t x;
30+
int8_t y[];
31+
} WithFlexibleArrayMember;
32+
2833
void root(struct Opaque *a,
2934
struct Normal b,
3035
struct NormalWithZST c,
3136
struct TupleRenamed d,
32-
struct TupleNamed e);
37+
struct TupleNamed e,
38+
struct WithFlexibleArrayMember f);

tests/expectations/struct_both.compat.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ typedef struct TupleNamed {
2525
float y;
2626
} TupleNamed;
2727

28+
typedef struct WithFlexibleArrayMember {
29+
int32_t x;
30+
int8_t y[];
31+
} WithFlexibleArrayMember;
32+
2833
#ifdef __cplusplus
2934
extern "C" {
3035
#endif // __cplusplus
@@ -33,7 +38,8 @@ void root(struct Opaque *a,
3338
struct Normal b,
3439
struct NormalWithZST c,
3540
struct TupleRenamed d,
36-
struct TupleNamed e);
41+
struct TupleNamed e,
42+
struct WithFlexibleArrayMember f);
3743

3844
#ifdef __cplusplus
3945
} // extern "C"

tests/expectations/struct_tag.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@ struct TupleNamed {
2525
float y;
2626
};
2727

28+
struct WithFlexibleArrayMember {
29+
int32_t x;
30+
int8_t y[];
31+
};
32+
2833
void root(struct Opaque *a,
2934
struct Normal b,
3035
struct NormalWithZST c,
3136
struct TupleRenamed d,
32-
struct TupleNamed e);
37+
struct TupleNamed e,
38+
struct WithFlexibleArrayMember f);

tests/expectations/struct_tag.compat.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ struct TupleNamed {
2525
float y;
2626
};
2727

28+
struct WithFlexibleArrayMember {
29+
int32_t x;
30+
int8_t y[];
31+
};
32+
2833
#ifdef __cplusplus
2934
extern "C" {
3035
#endif // __cplusplus
@@ -33,7 +38,8 @@ void root(struct Opaque *a,
3338
struct Normal b,
3439
struct NormalWithZST c,
3540
struct TupleRenamed d,
36-
struct TupleNamed e);
41+
struct TupleNamed e,
42+
struct WithFlexibleArrayMember f);
3743

3844
#ifdef __cplusplus
3945
} // extern "C"

tests/expectations/struct_tag.pyx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,13 @@ cdef extern from *:
2525
int32_t x;
2626
float y;
2727

28-
void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e);
28+
cdef struct WithFlexibleArrayMember:
29+
int32_t x;
30+
int8_t y[0];
31+
32+
void root(Opaque *a,
33+
Normal b,
34+
NormalWithZST c,
35+
TupleRenamed d,
36+
TupleNamed e,
37+
WithFlexibleArrayMember f);

tests/rust/struct.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,18 @@ struct TupleRenamed(i32, f32);
2828
#[repr(C)]
2929
struct TupleNamed(i32, f32);
3030

31+
#[repr(C)]
32+
struct WithFlexibleArrayMember {
33+
x: i32,
34+
y: [i8; 0],
35+
}
36+
3137
#[no_mangle]
3238
pub extern "C" fn root(
3339
a: *mut Opaque,
3440
b: Normal,
3541
c: NormalWithZST,
3642
d: TupleRenamed,
37-
e: TupleNamed
43+
e: TupleNamed,
44+
f: WithFlexibleArrayMember,
3845
) { }

0 commit comments

Comments
 (0)