Skip to content

Commit 0e2d977

Browse files
committed
Added support for #[repr(transparent)]
1 parent 090b815 commit 0e2d977

File tree

8 files changed

+183
-8
lines changed

8 files changed

+183
-8
lines changed

src/bindgen/ir/enumeration.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ impl EnumVariant {
8787
generic_params: GenericParams::default(),
8888
fields: parse_fields(is_tagged, &fields.named)?,
8989
is_tagged,
90+
is_transparent: false,
9091
tuple_struct: false,
9192
cfg: Cfg::append(mod_cfg, Cfg::load(&variant.attrs)),
9293
annotations: AnnotationSet::load(&variant.attrs)?,
@@ -97,6 +98,7 @@ impl EnumVariant {
9798
generic_params: GenericParams::default(),
9899
fields: parse_fields(is_tagged, &fields.unnamed)?,
99100
is_tagged,
101+
is_transparent: false,
100102
tuple_struct: true,
101103
cfg: Cfg::append(mod_cfg, Cfg::load(&variant.attrs)),
102104
annotations: AnnotationSet::load(&variant.attrs)?,

src/bindgen/ir/repr.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
use syn;
66

7-
#[derive(Debug, Copy, Clone, PartialEq)]
7+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
88
pub enum ReprStyle {
99
Rust,
1010
C,
11+
Transparent,
1112
}
1213

1314
impl Default for ReprStyle {
@@ -16,7 +17,7 @@ impl Default for ReprStyle {
1617
}
1718
}
1819

19-
#[derive(Debug, Copy, Clone, PartialEq)]
20+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2021
pub enum ReprType {
2122
U8,
2223
U16,
@@ -28,7 +29,7 @@ pub enum ReprType {
2829
ISize,
2930
}
3031

31-
#[derive(Debug, Copy, Clone, PartialEq, Default)]
32+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
3233
pub struct Repr {
3334
pub style: ReprStyle,
3435
pub ty: Option<ReprType>,
@@ -40,6 +41,11 @@ impl Repr {
4041
ty: None,
4142
};
4243

44+
pub const TRANSPARENT: Self = Repr {
45+
style: ReprStyle::Transparent,
46+
ty: None,
47+
};
48+
4349
pub const RUST: Self = Repr {
4450
style: ReprStyle::Rust,
4551
ty: None,
@@ -82,6 +88,10 @@ impl Repr {
8288
repr.style = ReprStyle::C;
8389
continue;
8490
}
91+
"transparent" => {
92+
repr.style = ReprStyle::Transparent;
93+
continue;
94+
}
8595
_ => {
8696
return Err(format!("Unsupported #[repr({})].", id));
8797
}

src/bindgen/ir/structure.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bindgen::declarationtyperesolver::DeclarationTypeResolver;
1111
use bindgen::dependencies::Dependencies;
1212
use bindgen::ir::{
1313
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Repr,
14-
ToCondition, Type,
14+
ToCondition, Type, Typedef,
1515
};
1616
use bindgen::library::Library;
1717
use bindgen::mangle;
@@ -26,6 +26,7 @@ pub struct Struct {
2626
pub generic_params: GenericParams,
2727
pub fields: Vec<(String, Type, Documentation)>,
2828
pub is_tagged: bool,
29+
pub is_transparent: bool,
2930
pub tuple_struct: bool,
3031
pub cfg: Option<Cfg>,
3132
pub annotations: AnnotationSet,
@@ -39,9 +40,13 @@ impl Struct {
3940
}
4041

4142
pub fn load(item: &syn::ItemStruct, mod_cfg: &Option<Cfg>) -> Result<Struct, String> {
42-
if Repr::load(&item.attrs)? != Repr::C {
43-
return Err("Struct is not marked #[repr(C)].".to_owned());
44-
}
43+
let is_transparent = match Repr::load(&item.attrs)? {
44+
Repr::C => false,
45+
Repr::TRANSPARENT => true,
46+
_ => {
47+
return Err("Struct is not marked #[repr(C)] or #[repr(transparent)].".to_owned());
48+
}
49+
};
4550

4651
let (fields, tuple_struct) = match &item.fields {
4752
&syn::Fields::Unit => (Vec::new(), false),
@@ -70,6 +75,7 @@ impl Struct {
7075
generic_params: GenericParams::new(&item.generics),
7176
fields: fields,
7277
is_tagged: false,
78+
is_transparent: is_transparent,
7379
tuple_struct: tuple_struct,
7480
cfg: Cfg::append(mod_cfg, Cfg::load(&item.attrs)),
7581
annotations: AnnotationSet::load(&item.attrs)?,
@@ -128,7 +134,9 @@ impl Item for Struct {
128134
}
129135

130136
fn collect_declaration_types(&self, resolver: &mut DeclarationTypeResolver) {
131-
resolver.add_struct(&self.name);
137+
if !self.is_transparent {
138+
resolver.add_struct(&self.name);
139+
}
132140
}
133141

134142
fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) {
@@ -225,6 +233,7 @@ impl Item for Struct {
225233
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
226234
.collect(),
227235
is_tagged: self.is_tagged,
236+
is_transparent: self.is_transparent,
228237
tuple_struct: self.tuple_struct,
229238
cfg: self.cfg.clone(),
230239
annotations: self.annotations.clone(),
@@ -240,6 +249,18 @@ impl Item for Struct {
240249

241250
impl Source for Struct {
242251
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
252+
if self.is_transparent {
253+
let typedef = Typedef {
254+
name: self.name.clone(),
255+
generic_params: self.generic_params.clone(),
256+
aliased: self.fields[0].1.clone(),
257+
cfg: self.cfg.clone(),
258+
annotations: self.annotations.clone(),
259+
documentation: self.documentation.clone(),
260+
};
261+
return typedef.write(config, out);
262+
}
263+
243264
let condition = (&self.cfg).to_condition(config);
244265
condition.write_before(config, out);
245266

tests/expectations/both/transparent.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
#include <stdbool.h>
4+
5+
typedef struct DummyStruct DummyStruct;
6+
7+
typedef DummyStruct TransparentComplexWrappingStructTuple;
8+
9+
typedef uint32_t TransparentPrimitiveWrappingStructTuple;
10+
11+
typedef DummyStruct TransparentComplexWrappingStructure;
12+
13+
typedef uint32_t TransparentPrimitiveWrappingStructure;
14+
15+
typedef DummyStruct TransparentComplexWrapper_i32;
16+
17+
typedef uint32_t TransparentPrimitiveWrapper_i32;
18+
19+
void root(TransparentComplexWrappingStructTuple a,
20+
TransparentPrimitiveWrappingStructTuple b,
21+
TransparentComplexWrappingStructure c,
22+
TransparentPrimitiveWrappingStructure d,
23+
TransparentComplexWrapper_i32 e,
24+
TransparentPrimitiveWrapper_i32 f);

tests/expectations/tag/transparent.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
#include <stdbool.h>
4+
5+
struct DummyStruct;
6+
7+
typedef struct DummyStruct TransparentComplexWrappingStructTuple;
8+
9+
typedef uint32_t TransparentPrimitiveWrappingStructTuple;
10+
11+
typedef struct DummyStruct TransparentComplexWrappingStructure;
12+
13+
typedef uint32_t TransparentPrimitiveWrappingStructure;
14+
15+
typedef struct DummyStruct TransparentComplexWrapper_i32;
16+
17+
typedef uint32_t TransparentPrimitiveWrapper_i32;
18+
19+
void root(TransparentComplexWrappingStructTuple a,
20+
TransparentPrimitiveWrappingStructTuple b,
21+
TransparentComplexWrappingStructure c,
22+
TransparentPrimitiveWrappingStructure d,
23+
TransparentComplexWrapper_i32 e,
24+
TransparentPrimitiveWrapper_i32 f);

tests/expectations/transparent.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
#include <stdbool.h>
4+
5+
typedef struct DummyStruct DummyStruct;
6+
7+
typedef DummyStruct TransparentComplexWrappingStructTuple;
8+
9+
typedef uint32_t TransparentPrimitiveWrappingStructTuple;
10+
11+
typedef DummyStruct TransparentComplexWrappingStructure;
12+
13+
typedef uint32_t TransparentPrimitiveWrappingStructure;
14+
15+
typedef DummyStruct TransparentComplexWrapper_i32;
16+
17+
typedef uint32_t TransparentPrimitiveWrapper_i32;
18+
19+
void root(TransparentComplexWrappingStructTuple a,
20+
TransparentPrimitiveWrappingStructTuple b,
21+
TransparentComplexWrappingStructure c,
22+
TransparentPrimitiveWrappingStructure d,
23+
TransparentComplexWrapper_i32 e,
24+
TransparentPrimitiveWrapper_i32 f);

tests/expectations/transparent.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <cstdint>
2+
#include <cstdlib>
3+
4+
struct DummyStruct;
5+
6+
using TransparentComplexWrappingStructTuple = DummyStruct;
7+
8+
using TransparentPrimitiveWrappingStructTuple = uint32_t;
9+
10+
using TransparentComplexWrappingStructure = DummyStruct;
11+
12+
using TransparentPrimitiveWrappingStructure = uint32_t;
13+
14+
template<typename T>
15+
using TransparentComplexWrapper = DummyStruct;
16+
17+
template<typename T>
18+
using TransparentPrimitiveWrapper = uint32_t;
19+
20+
extern "C" {
21+
22+
void root(TransparentComplexWrappingStructTuple a,
23+
TransparentPrimitiveWrappingStructTuple b,
24+
TransparentComplexWrappingStructure c,
25+
TransparentPrimitiveWrappingStructure d,
26+
TransparentComplexWrapper<int32_t> e,
27+
TransparentPrimitiveWrapper<int32_t> f);
28+
29+
} // extern "C"

tests/rust/transparent.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
struct DummyStruct;
2+
3+
// Transparent struct tuple wrapping a struct.
4+
#[repr(transparent)]
5+
struct TransparentComplexWrappingStructTuple(DummyStruct);
6+
7+
// Transparent struct tuple wrapping a primitive.
8+
#[repr(transparent)]
9+
struct TransparentPrimitiveWrappingStructTuple(u32);
10+
11+
// Transparent structure wrapping a struct.
12+
#[repr(transparent)]
13+
struct TransparentComplexWrappingStructure { only_field: DummyStruct }
14+
15+
// Transparent structure wrapping a primitive.
16+
#[repr(transparent)]
17+
struct TransparentPrimitiveWrappingStructure { only_field: u32 }
18+
19+
// Transparent struct wrapper with a marker wrapping a struct.
20+
#[repr(transparent)]
21+
struct TransparentComplexWrapper<T> {
22+
only_non_zero_sized_field: DummyStruct,
23+
marker: PhantomData<T>,
24+
}
25+
26+
// Transparent struct wrapper with a marker wrapping a primitive.
27+
#[repr(transparent)]
28+
struct TransparentPrimitiveWrapper<T> {
29+
only_non_zero_sized_field: u32,
30+
marker: PhantomData<T>,
31+
}
32+
33+
#[no_mangle]
34+
pub extern "C" fn root(
35+
a: TransparentComplexWrappingStructTuple,
36+
b: TransparentPrimitiveWrappingStructTuple,
37+
c: TransparentComplexWrappingStructure,
38+
d: TransparentPrimitiveWrappingStructure,
39+
e: TransparentComplexWrapper<i32>,
40+
f: TransparentPrimitiveWrapper<i32>,
41+
) { }

0 commit comments

Comments
 (0)