Added support for #[repr(transparent)]

This commit is contained in:
Vincent Esche
2018-08-03 02:13:14 +02:00
committed by Ryan Hunt
parent 090b8154dd
commit 5e6d58dfe3
8 changed files with 183 additions and 8 deletions
+2
View File
@@ -87,6 +87,7 @@ impl EnumVariant {
generic_params: GenericParams::default(),
fields: parse_fields(is_tagged, &fields.named)?,
is_tagged,
is_transparent: false,
tuple_struct: false,
cfg: Cfg::append(mod_cfg, Cfg::load(&variant.attrs)),
annotations: AnnotationSet::load(&variant.attrs)?,
@@ -97,6 +98,7 @@ impl EnumVariant {
generic_params: GenericParams::default(),
fields: parse_fields(is_tagged, &fields.unnamed)?,
is_tagged,
is_transparent: false,
tuple_struct: true,
cfg: Cfg::append(mod_cfg, Cfg::load(&variant.attrs)),
annotations: AnnotationSet::load(&variant.attrs)?,
+13 -3
View File
@@ -4,10 +4,11 @@
use syn;
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ReprStyle {
Rust,
C,
Transparent,
}
impl Default for ReprStyle {
@@ -16,7 +17,7 @@ impl Default for ReprStyle {
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ReprType {
U8,
U16,
@@ -28,7 +29,7 @@ pub enum ReprType {
ISize,
}
#[derive(Debug, Copy, Clone, PartialEq, Default)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub struct Repr {
pub style: ReprStyle,
pub ty: Option<ReprType>,
@@ -40,6 +41,11 @@ impl Repr {
ty: None,
};
pub const TRANSPARENT: Self = Repr {
style: ReprStyle::Transparent,
ty: None,
};
pub const RUST: Self = Repr {
style: ReprStyle::Rust,
ty: None,
@@ -82,6 +88,10 @@ impl Repr {
repr.style = ReprStyle::C;
continue;
}
"transparent" => {
repr.style = ReprStyle::Transparent;
continue;
}
_ => {
return Err(format!("Unsupported #[repr({})].", id));
}
+26 -5
View File
@@ -11,7 +11,7 @@ use bindgen::declarationtyperesolver::DeclarationTypeResolver;
use bindgen::dependencies::Dependencies;
use bindgen::ir::{
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Repr,
ToCondition, Type,
ToCondition, Type, Typedef,
};
use bindgen::library::Library;
use bindgen::mangle;
@@ -26,6 +26,7 @@ pub struct Struct {
pub generic_params: GenericParams,
pub fields: Vec<(String, Type, Documentation)>,
pub is_tagged: bool,
pub is_transparent: bool,
pub tuple_struct: bool,
pub cfg: Option<Cfg>,
pub annotations: AnnotationSet,
@@ -39,9 +40,13 @@ impl Struct {
}
pub fn load(item: &syn::ItemStruct, mod_cfg: &Option<Cfg>) -> Result<Struct, String> {
if Repr::load(&item.attrs)? != Repr::C {
return Err("Struct is not marked #[repr(C)].".to_owned());
}
let is_transparent = match Repr::load(&item.attrs)? {
Repr::C => false,
Repr::TRANSPARENT => true,
_ => {
return Err("Struct is not marked #[repr(C)] or #[repr(transparent)].".to_owned());
}
};
let (fields, tuple_struct) = match &item.fields {
&syn::Fields::Unit => (Vec::new(), false),
@@ -70,6 +75,7 @@ impl Struct {
generic_params: GenericParams::new(&item.generics),
fields: fields,
is_tagged: false,
is_transparent: is_transparent,
tuple_struct: tuple_struct,
cfg: Cfg::append(mod_cfg, Cfg::load(&item.attrs)),
annotations: AnnotationSet::load(&item.attrs)?,
@@ -128,7 +134,9 @@ impl Item for Struct {
}
fn collect_declaration_types(&self, resolver: &mut DeclarationTypeResolver) {
resolver.add_struct(&self.name);
if !self.is_transparent {
resolver.add_struct(&self.name);
}
}
fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) {
@@ -225,6 +233,7 @@ impl Item for Struct {
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
is_tagged: self.is_tagged,
is_transparent: self.is_transparent,
tuple_struct: self.tuple_struct,
cfg: self.cfg.clone(),
annotations: self.annotations.clone(),
@@ -240,6 +249,18 @@ impl Item for Struct {
impl Source for Struct {
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
if self.is_transparent {
let typedef = Typedef {
name: self.name.clone(),
generic_params: self.generic_params.clone(),
aliased: self.fields[0].1.clone(),
cfg: self.cfg.clone(),
annotations: self.annotations.clone(),
documentation: self.documentation.clone(),
};
return typedef.write(config, out);
}
let condition = (&self.cfg).to_condition(config);
condition.write_before(config, out);
+24
View File
@@ -0,0 +1,24 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct DummyStruct DummyStruct;
typedef DummyStruct TransparentComplexWrappingStructTuple;
typedef uint32_t TransparentPrimitiveWrappingStructTuple;
typedef DummyStruct TransparentComplexWrappingStructure;
typedef uint32_t TransparentPrimitiveWrappingStructure;
typedef DummyStruct TransparentComplexWrapper_i32;
typedef uint32_t TransparentPrimitiveWrapper_i32;
void root(TransparentComplexWrappingStructTuple a,
TransparentPrimitiveWrappingStructTuple b,
TransparentComplexWrappingStructure c,
TransparentPrimitiveWrappingStructure d,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f);
+24
View File
@@ -0,0 +1,24 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
struct DummyStruct;
typedef struct DummyStruct TransparentComplexWrappingStructTuple;
typedef uint32_t TransparentPrimitiveWrappingStructTuple;
typedef struct DummyStruct TransparentComplexWrappingStructure;
typedef uint32_t TransparentPrimitiveWrappingStructure;
typedef struct DummyStruct TransparentComplexWrapper_i32;
typedef uint32_t TransparentPrimitiveWrapper_i32;
void root(TransparentComplexWrappingStructTuple a,
TransparentPrimitiveWrappingStructTuple b,
TransparentComplexWrappingStructure c,
TransparentPrimitiveWrappingStructure d,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f);
+24
View File
@@ -0,0 +1,24 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct DummyStruct DummyStruct;
typedef DummyStruct TransparentComplexWrappingStructTuple;
typedef uint32_t TransparentPrimitiveWrappingStructTuple;
typedef DummyStruct TransparentComplexWrappingStructure;
typedef uint32_t TransparentPrimitiveWrappingStructure;
typedef DummyStruct TransparentComplexWrapper_i32;
typedef uint32_t TransparentPrimitiveWrapper_i32;
void root(TransparentComplexWrappingStructTuple a,
TransparentPrimitiveWrappingStructTuple b,
TransparentComplexWrappingStructure c,
TransparentPrimitiveWrappingStructure d,
TransparentComplexWrapper_i32 e,
TransparentPrimitiveWrapper_i32 f);
+29
View File
@@ -0,0 +1,29 @@
#include <cstdint>
#include <cstdlib>
struct DummyStruct;
using TransparentComplexWrappingStructTuple = DummyStruct;
using TransparentPrimitiveWrappingStructTuple = uint32_t;
using TransparentComplexWrappingStructure = DummyStruct;
using TransparentPrimitiveWrappingStructure = uint32_t;
template<typename T>
using TransparentComplexWrapper = DummyStruct;
template<typename T>
using TransparentPrimitiveWrapper = uint32_t;
extern "C" {
void root(TransparentComplexWrappingStructTuple a,
TransparentPrimitiveWrappingStructTuple b,
TransparentComplexWrappingStructure c,
TransparentPrimitiveWrappingStructure d,
TransparentComplexWrapper<int32_t> e,
TransparentPrimitiveWrapper<int32_t> f);
} // extern "C"
+41
View File
@@ -0,0 +1,41 @@
struct DummyStruct;
// Transparent struct tuple wrapping a struct.
#[repr(transparent)]
struct TransparentComplexWrappingStructTuple(DummyStruct);
// Transparent struct tuple wrapping a primitive.
#[repr(transparent)]
struct TransparentPrimitiveWrappingStructTuple(u32);
// Transparent structure wrapping a struct.
#[repr(transparent)]
struct TransparentComplexWrappingStructure { only_field: DummyStruct }
// Transparent structure wrapping a primitive.
#[repr(transparent)]
struct TransparentPrimitiveWrappingStructure { only_field: u32 }
// Transparent struct wrapper with a marker wrapping a struct.
#[repr(transparent)]
struct TransparentComplexWrapper<T> {
only_non_zero_sized_field: DummyStruct,
marker: PhantomData<T>,
}
// Transparent struct wrapper with a marker wrapping a primitive.
#[repr(transparent)]
struct TransparentPrimitiveWrapper<T> {
only_non_zero_sized_field: u32,
marker: PhantomData<T>,
}
#[no_mangle]
pub extern "C" fn root(
a: TransparentComplexWrappingStructTuple,
b: TransparentPrimitiveWrappingStructTuple,
c: TransparentComplexWrappingStructure,
d: TransparentPrimitiveWrappingStructure,
e: TransparentComplexWrapper<i32>,
f: TransparentPrimitiveWrapper<i32>,
) { }