Added support for #[repr(transparent)]
This commit is contained in:
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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"
|
||||
@@ -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>,
|
||||
) { }
|
||||
Reference in New Issue
Block a user