Skip to content

Commit

Permalink
add missing test case for empty transparent struct
Browse files Browse the repository at this point in the history
  • Loading branch information
scovich committed Aug 12, 2024
1 parent ba96d90 commit f6d956d
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 18 deletions.
16 changes: 8 additions & 8 deletions src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,16 @@ impl Struct {
/// Attempts to convert this struct to a typedef (only works for transparent structs).
pub fn as_typedef(&self) -> Option<Typedef> {
if self.is_transparent {
// NOTE: A `#[repr(transparent)]` struct with 2+ NZT fields fails to compile, but 0
// fields is allowed for some strange reason. Don't emit the typedef in that case.
// NOTE: The rust compiler rejects a `#[repr(transparent)]` struct with 2+ NZST fields,
// but accepts an empty struct (see https://github.com/rust-lang/rust/issues/129029).
// Don't emit the typedef in that case.
if let Some(field) = self.fields.first() {
return Some(Typedef::new_from_struct_field(self, field));
} else {
error!(
"Cannot convert empty transparent struct {} to typedef",
self.name()
);
}
error!(
"Cannot convert empty transparent struct {} to typedef",
self.name()
);
}
None
}
Expand Down Expand Up @@ -288,7 +288,7 @@ impl Item for Struct {
}

fn collect_declaration_types(&self, resolver: &mut DeclarationTypeResolver) {
if self.is_transparent {
if self.is_transparent && self.fields.len() == 1 {
resolver.add_none(&self.path);
} else {
resolver.add_struct(&self.path);
Expand Down
7 changes: 6 additions & 1 deletion tests/expectations/transparent.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
#define TransparentPrimitiveWithAssociatedConstants_ONE 1

typedef struct {

} TransparentEmptyStructure;

#define EnumWithAssociatedConstantInImpl_TEN 10

void root(TransparentComplexWrappingStructTuple a,
Expand All @@ -32,4 +36,5 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);
7 changes: 6 additions & 1 deletion tests/expectations/transparent.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
#define TransparentPrimitiveWithAssociatedConstants_ONE 1

typedef struct {

} TransparentEmptyStructure;

#define EnumWithAssociatedConstantInImpl_TEN 10

#ifdef __cplusplus
Expand All @@ -36,7 +40,8 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);

#ifdef __cplusplus
} // extern "C"
Expand Down
7 changes: 6 additions & 1 deletion tests/expectations/transparent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ using TransparentPrimitiveWithAssociatedConstants = uint32_t;
constexpr static const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ZERO = 0;
constexpr static const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ONE = 1;

struct TransparentEmptyStructure {

};

constexpr static const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN = 10;

extern "C" {
Expand All @@ -37,6 +41,7 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper<int32_t> e,
TransparentPrimitiveWrapper<int32_t> f,
TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);

} // extern "C"
6 changes: 5 additions & 1 deletion tests/expectations/transparent.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ cdef extern from *:
const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ZERO # = 0
const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ONE # = 1

ctypedef struct TransparentEmptyStructure:
pass

const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN # = 10

void root(TransparentComplexWrappingStructTuple a,
Expand All @@ -37,4 +40,5 @@ cdef extern from *:
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);
7 changes: 6 additions & 1 deletion tests/expectations/transparent_both.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
#define TransparentPrimitiveWithAssociatedConstants_ONE 1

typedef struct TransparentEmptyStructure {

} TransparentEmptyStructure;

#define EnumWithAssociatedConstantInImpl_TEN 10

void root(TransparentComplexWrappingStructTuple a,
Expand All @@ -32,4 +36,5 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);
7 changes: 6 additions & 1 deletion tests/expectations/transparent_both.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
#define TransparentPrimitiveWithAssociatedConstants_ONE 1

typedef struct TransparentEmptyStructure {

} TransparentEmptyStructure;

#define EnumWithAssociatedConstantInImpl_TEN 10

#ifdef __cplusplus
Expand All @@ -36,7 +40,8 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);

#ifdef __cplusplus
} // extern "C"
Expand Down
7 changes: 6 additions & 1 deletion tests/expectations/transparent_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
#define TransparentPrimitiveWithAssociatedConstants_ONE 1

struct TransparentEmptyStructure {

};

#define EnumWithAssociatedConstantInImpl_TEN 10

void root(TransparentComplexWrappingStructTuple a,
Expand All @@ -32,4 +36,5 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);
7 changes: 6 additions & 1 deletion tests/expectations/transparent_tag.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
#define TransparentPrimitiveWithAssociatedConstants_ONE 1

struct TransparentEmptyStructure {

};

#define EnumWithAssociatedConstantInImpl_TEN 10

#ifdef __cplusplus
Expand All @@ -36,7 +40,8 @@ void root(TransparentComplexWrappingStructTuple a,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);

#ifdef __cplusplus
} // extern "C"
Expand Down
6 changes: 5 additions & 1 deletion tests/expectations/transparent_tag.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ cdef extern from *:
const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ZERO # = 0
const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ONE # = 1

cdef struct TransparentEmptyStructure:
pass

const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN # = 10

void root(TransparentComplexWrappingStructTuple a,
Expand All @@ -37,4 +40,5 @@ cdef extern from *:
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f,
TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);
8 changes: 7 additions & 1 deletion tests/rust/transparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ impl TransparentPrimitiveWithAssociatedConstants {
#[repr(transparent)]
struct TransparentPrimitiveWithAssociatedConstants { bits: u32 }

// https://github.com/rust-lang/rust/issues/129029 the rust compiler (wrongly?) accepts this, but
// cbindgen should nevertheless emit the struct definition instead of a typedef.
#[repr(transparent)]
struct TransparentEmptyStructure;

// Associated constant declared after struct declaration.
impl TransparentPrimitiveWithAssociatedConstants {
pub const ONE: TransparentPrimitiveWithAssociatedConstants = TransparentPrimitiveWithAssociatedConstants {
Expand All @@ -63,5 +68,6 @@ pub extern "C" fn root(
e: TransparentComplexWrapper<i32>,
f: TransparentPrimitiveWrapper<i32>,
g: TransparentPrimitiveWithAssociatedConstants,
h: EnumWithAssociatedConstantInImpl,
h: TransparentEmptyStructure,
i: EnumWithAssociatedConstantInImpl,
) { }

0 comments on commit f6d956d

Please sign in to comment.