Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate flexible array members the c99 way instead of the GNU way #994

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
23 changes: 22 additions & 1 deletion src/bindgen/cdecl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum CDeclarator {
is_ref: bool,
},
Array(String),
FlexibleArray(),
Func {
args: Vec<(Option<String>, CDecl)>,
layout: Layout,
Expand Down Expand Up @@ -167,6 +168,10 @@ impl CDecl {
self.declarators.push(CDeclarator::Array(len));
self.build_type(t, is_const, config);
}
Type::FlexibleArray(ref t) => {
self.declarators.push(CDeclarator::FlexibleArray());
self.build_type(t, is_const, config);
}
Type::FuncPtr {
ref ret,
ref args,
Expand Down Expand Up @@ -254,7 +259,7 @@ impl CDecl {
}
}
}
CDeclarator::Array(..) => {
CDeclarator::Array(..) | CDeclarator::FlexibleArray() => {
if next_is_pointer {
out.write("(");
}
Expand Down Expand Up @@ -286,10 +291,26 @@ impl CDecl {
if last_was_pointer {
out.write(")");
}

write!(out, "[{}]", constant);

last_was_pointer = false;
}
CDeclarator::FlexibleArray() => {
if last_was_pointer {
out.write(")");
}

if config.structure.c99_flexible_array_members
&& config.language != Language::Cython
{
write!(out, "[]");
} else {
write!(out, "[0]");
}

last_was_pointer = false;
}
CDeclarator::Func {
ref args,
ref layout,
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 c99_flexible_array_members: bool,
}

impl StructConfig {
Expand Down
16 changes: 15 additions & 1 deletion src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl Struct {
layout_config.ensure_safe_to_represent(&align)?;
}

let fields = match item.fields {
let mut fields = match item.fields {
syn::Fields::Unit => Vec::new(),
syn::Fields::Named(ref fields) => fields
.named
Expand All @@ -97,6 +97,20 @@ impl Struct {
}
};

match fields.last() {
Some(Field {
name: _,
ty: Type::Array(ty, sz),
cfg: _,
annotations: _,
documentation: _,
}) if sz.as_str() == "0" => {
let last_index = fields.len() - 1;
fields[last_index].ty = Type::FlexibleArray(ty.clone());
}
_ => (),
}

let has_tag_field = false;
let is_enum_variant_body = false;

Expand Down
21 changes: 15 additions & 6 deletions src/bindgen/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ pub enum Type {
Path(GenericPath),
Primitive(PrimitiveType),
Array(Box<Type>, ConstExpr),
FlexibleArray(Box<Type>),
FuncPtr {
ret: Box<Type>,
args: Vec<(Option<String>, Type)>,
Expand Down Expand Up @@ -583,7 +584,9 @@ impl Type {

fn visit_types(&mut self, mut visitor: impl FnMut(&mut Type)) {
match *self {
Type::Array(ref mut ty, ..) | Type::Ptr { ref mut ty, .. } => visitor(ty),
Type::Array(ref mut ty, ..)
| Type::FlexibleArray(ref mut ty)
| Type::Ptr { ref mut ty, .. } => visitor(ty),
Type::Path(ref mut path) => {
for generic in path.generics_mut() {
match *generic {
Expand Down Expand Up @@ -617,7 +620,7 @@ impl Type {
Type::Primitive(..) => {
return None;
}
Type::Array(..) => {
Type::Array(..) | Type::FlexibleArray(..) => {
return None;
}
Type::FuncPtr { .. } => {
Expand Down Expand Up @@ -664,6 +667,7 @@ impl Type {
Box::new(ty.specialize(mappings)),
constant.specialize(mappings),
),
Type::FlexibleArray(ref ty) => Type::FlexibleArray(Box::new(ty.specialize(mappings))),
Type::FuncPtr {
ref ret,
ref args,
Expand Down Expand Up @@ -721,7 +725,7 @@ impl Type {
}
}
Type::Primitive(_) => {}
Type::Array(ref ty, _) => {
Type::Array(ref ty, _) | Type::FlexibleArray(ref ty) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
}
Type::FuncPtr {
Expand Down Expand Up @@ -757,7 +761,7 @@ impl Type {
}
}
Type::Primitive(_) => {}
Type::Array(ref ty, _) => {
Type::Array(ref ty, _) | Type::FlexibleArray(ref ty) => {
ty.add_monomorphs(library, out);
}
Type::FuncPtr {
Expand All @@ -784,6 +788,9 @@ impl Type {
ty.rename_for_config(config, generic_params);
len.rename_for_config(config);
}
Type::FlexibleArray(ref mut ty) => {
ty.rename_for_config(config, generic_params);
}
Type::FuncPtr {
ref mut ret,
ref mut args,
Expand All @@ -806,7 +813,7 @@ impl Type {
generic_path.resolve_declaration_types(resolver);
}
Type::Primitive(_) => {}
Type::Array(ref mut ty, _) => {
Type::Array(ref mut ty, _) | Type::FlexibleArray(ref mut ty) => {
ty.resolve_declaration_types(resolver);
}
Type::FuncPtr {
Expand Down Expand Up @@ -843,7 +850,7 @@ impl Type {
}
}
Type::Primitive(_) => {}
Type::Array(ref mut ty, _) => {
Type::Array(ref mut ty, _) | Type::FlexibleArray(ref mut ty) => {
ty.mangle_paths(monomorphs);
}
Type::FuncPtr {
Expand All @@ -866,6 +873,7 @@ impl Type {
Type::Path(..) => true,
Type::Primitive(ref p) => p.can_cmp_order(),
Type::Array(..) => false,
Type::FlexibleArray(..) => false,
Type::FuncPtr { .. } => false,
}
}
Expand All @@ -876,6 +884,7 @@ impl Type {
Type::Path(..) => true,
Type::Primitive(ref p) => p.can_cmp_eq(),
Type::Array(..) => false,
Type::FlexibleArray(..) => false,
Type::FuncPtr { .. } => true,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/bindgen/mangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl<'a> Mangler<'a> {
self.push(Separator::EndFn);
}
}
Type::Array(..) => {
Type::Array(..) | Type::FlexibleArray(..) => {
unimplemented!(
"Unable to mangle generic parameter {:?} for '{}'",
ty,
Expand Down
13 changes: 12 additions & 1 deletion tests/expectations/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,15 @@ typedef struct {
float y;
} TupleNamed;

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

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

typedef struct {
int32_t x;
int16_t y[0];
int8_t z[0];
} 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
13 changes: 12 additions & 1 deletion tests/expectations/struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,19 @@ struct TupleNamed {
float y;
};

struct WithFlexibleArrayMember {
int32_t x;
int16_t y[0];
int8_t z[0];
};

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"
12 changes: 11 additions & 1 deletion tests/expectations/struct.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,14 @@ 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;
int16_t y[0];
int8_t z[0];

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

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

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

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

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
Expand All @@ -33,7 +39,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
9 changes: 8 additions & 1 deletion tests/expectations/struct_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ struct TupleNamed {
float y;
};

struct WithFlexibleArrayMember {
int32_t x;
int16_t y[0];
int8_t z[0];
};

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

struct WithFlexibleArrayMember {
int32_t x;
int16_t y[0];
int8_t z[0];
};

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
Expand All @@ -33,7 +39,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
12 changes: 11 additions & 1 deletion tests/expectations/struct_tag.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,14 @@ 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;
int16_t y[0];
int8_t z[0];

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

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

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