diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clang.rs | 1 | ||||
-rw-r--r-- | src/codegen/impl_debug.rs | 4 | ||||
-rw-r--r-- | src/codegen/impl_partialeq.rs | 4 | ||||
-rw-r--r-- | src/codegen/mod.rs | 101 | ||||
-rw-r--r-- | src/ir/analysis/derive_copy.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/derive_debug.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/derive_default.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/derive_hash.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/derive_partialeq_or_partialord.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/has_float.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/has_type_param_in_array.rs | 4 | ||||
-rw-r--r-- | src/ir/analysis/sizedness.rs | 2 | ||||
-rw-r--r-- | src/ir/ty.rs | 23 | ||||
-rw-r--r-- | src/lib.rs | 16 | ||||
-rw-r--r-- | src/options.rs | 7 |
15 files changed, 141 insertions, 45 deletions
diff --git a/src/clang.rs b/src/clang.rs index 78bbd07c..f8f7e581 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -940,6 +940,7 @@ impl Type { CXType_RValueReference | CXType_LValueReference | CXType_MemberPointer | + CXType_BlockPointer | CXType_ObjCObjectPointer => { let ret = Type { x: unsafe { clang_getPointeeType(self.x) }, diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index 077d5737..0f8e4d96 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -156,7 +156,6 @@ impl<'a> ImplDebug<'a> for Item { TypeKind::Function(..) | TypeKind::Enum(..) | TypeKind::Reference(..) | - TypeKind::BlockPointer | TypeKind::UnresolvedTypeRef(..) | TypeKind::ObjCInterface(..) | TypeKind::ObjCId | @@ -227,7 +226,8 @@ impl<'a> ImplDebug<'a> for Item { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { // We follow the aliases ctx.resolve_item(t).impl_debug(ctx, name) } diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs index 66565db6..c8ff6313 100644 --- a/src/codegen/impl_partialeq.rs +++ b/src/codegen/impl_partialeq.rs @@ -88,7 +88,6 @@ fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens TypeKind::Enum(..) | TypeKind::TypeParam | TypeKind::UnresolvedTypeRef(..) | - TypeKind::BlockPointer | TypeKind::Reference(..) | TypeKind::ObjCInterface(..) | TypeKind::ObjCId | @@ -125,7 +124,8 @@ fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { let inner_item = ctx.resolve_item(t); gen_field(ctx, inner_item, name) } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index d1da6afc..5a4ccc72 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -103,6 +103,9 @@ struct CodegenResult<'a> { /// Whether Objective C types have been seen at least once. saw_objc: bool, + /// Whether Apple block types have been seen at least once. + saw_block: bool, + /// Whether a bitfield allocation unit has been seen at least once. saw_bitfield_unit: bool, @@ -140,6 +143,7 @@ impl<'a> CodegenResult<'a> { saw_bindgen_union: false, saw_incomplete_array: false, saw_objc: false, + saw_block: false, saw_bitfield_unit: false, codegen_id: codegen_id, items_seen: Default::default(), @@ -166,6 +170,10 @@ impl<'a> CodegenResult<'a> { self.saw_objc = true; } + fn saw_block(&mut self) { + self.saw_block = true; + } + fn saw_bitfield_unit(&mut self) { self.saw_bitfield_unit = true; } @@ -215,6 +223,7 @@ impl<'a> CodegenResult<'a> { self.saw_union |= new.saw_union; self.saw_incomplete_array |= new.saw_incomplete_array; self.saw_objc |= new.saw_objc; + self.saw_block |= new.saw_block; self.saw_bitfield_unit |= new.saw_bitfield_unit; new.items @@ -293,7 +302,6 @@ impl AppendImplicitTemplateParams for quote::Tokens { TypeKind::Opaque | TypeKind::Function(..) | TypeKind::Enum(..) | - TypeKind::BlockPointer | TypeKind::ObjCId | TypeKind::ObjCSel | TypeKind::TemplateInstantiation(..) => return, @@ -394,6 +402,9 @@ impl CodeGenerator for Module { } if item.id() == ctx.root_module() { + if result.saw_block { + utils::prepend_block_header(ctx, &mut *result); + } if result.saw_bindgen_union { utils::prepend_union_types(ctx, &mut *result); } @@ -597,7 +608,6 @@ impl CodeGenerator for Type { TypeKind::Array(..) | TypeKind::Vector(..) | TypeKind::Pointer(..) | - TypeKind::BlockPointer | TypeKind::Reference(..) | TypeKind::Function(..) | TypeKind::ResolvedTypeRef(..) | @@ -610,6 +620,35 @@ impl CodeGenerator for Type { TypeKind::TemplateInstantiation(ref inst) => { inst.codegen(ctx, result, item) } + TypeKind::BlockPointer(inner) => { + let inner_item = inner.into_resolver() + .through_type_refs() + .resolve(ctx); + let name = item.canonical_name(ctx); + + let inner_rust_type = { + if let TypeKind::Function(fnsig) = inner_item.kind().expect_type().kind() { + utils::fnsig_block(ctx, fnsig) + } else { + panic!("invalid block typedef: {:?}", inner_item) + } + }; + + let rust_name = ctx.rust_ident(&name); + + let mut tokens = if let Some(comment) = item.comment(ctx) { + attributes::doc(comment) + } else { + quote! {} + }; + + tokens.append_all(quote! { + pub type #rust_name = #inner_rust_type ; + }); + + result.push(tokens); + result.saw_block(); + } TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item), TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => { @@ -3071,20 +3110,16 @@ impl TryToRustTy for Type { } TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()), TypeKind::TemplateAlias(..) | - TypeKind::Alias(..) => { + TypeKind::Alias(..) | + TypeKind::BlockPointer(..) => { let template_params = item.used_template_params(ctx) .into_iter() .filter(|param| param.is_template_param(ctx, &())) .collect::<Vec<_>>(); - let spelling = self.name().expect("Unnamed alias?"); if item.is_opaque(ctx, &()) && !template_params.is_empty() { self.try_to_opaque(ctx, item) - } else if let Some(ty) = utils::type_from_named( - ctx, - spelling, - ) - { + } else if let Some(ty) = self.name().and_then(|name| utils::type_from_named(ctx, name)) { Ok(ty) } else { utils::build_path(item, ctx) @@ -3101,13 +3136,6 @@ impl TryToRustTy for Type { utils::build_path(item, ctx) } TypeKind::Opaque => self.try_to_opaque(ctx, item), - TypeKind::BlockPointer => { - let void = raw_type(ctx, "c_void"); - Ok(void.to_ptr( - /* is_const = */ - false - )) - } TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { let is_const = ctx.resolve_type(inner).is_const(); @@ -3560,6 +3588,25 @@ mod utils { result.extend(old_items.into_iter()); } + pub fn prepend_block_header( + ctx: &BindgenContext, + result: &mut Vec<quote::Tokens>, + ) { + let use_block = if ctx.options().block_extern_crate { + quote! { + extern crate block; + } + } else { + quote! { + use block; + } + }; + + let items = vec![use_block]; + let old_items = mem::replace(result, items); + result.extend(old_items.into_iter()); + } + pub fn prepend_union_types( ctx: &BindgenContext, result: &mut Vec<quote::Tokens>, @@ -3871,4 +3918,26 @@ mod utils { args } + + pub fn fnsig_block( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> quote::Tokens { + let args = sig.argument_types().iter().map(|&(_, ty)| { + let arg_item = ctx.resolve_item(ty); + + arg_item.to_rust_ty_or_opaque(ctx, &()) + }); + + let return_item = ctx.resolve_item(sig.return_type()); + let ret_ty = if let TypeKind::Void = *return_item.kind().expect_type().kind() { + quote! { () } + } else { + return_item.to_rust_ty_or_opaque(ctx, &()) + }; + + quote! { + *const ::block::Block<(#(#args),*), #ret_ty> + } + } } diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index abb25174..fbe6e882 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -173,7 +173,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { TypeKind::Enum(..) | TypeKind::Reference(..) | TypeKind::TypeParam | - TypeKind::BlockPointer | TypeKind::Pointer(..) | TypeKind::UnresolvedTypeRef(..) | TypeKind::ObjCInterface(..) | @@ -204,7 +203,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { let cant_derive_copy = self.is_not_copy(t); if cant_derive_copy { trace!( diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index b0d70f15..5839f9ed 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -183,7 +183,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::Enum(..) | TypeKind::Reference(..) | TypeKind::Vector(..) | - TypeKind::BlockPointer | TypeKind::TypeParam | TypeKind::UnresolvedTypeRef(..) | TypeKind::ObjCInterface(..) | @@ -213,7 +212,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { if self.is_not_debug(t) { trace!( " aliases and type refs to T which cannot derive \ diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index a43d7737..cc322e9b 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -215,7 +215,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { TypeKind::Reference(..) | TypeKind::NullPtr | TypeKind::Pointer(..) | - TypeKind::BlockPointer | TypeKind::ObjCId | TypeKind::ObjCSel | TypeKind::ObjCInterface(..) | @@ -244,7 +243,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { if self.is_not_default(t) { trace!( " aliases and type refs to T which cannot derive \ diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index fe56ed7c..18c14a31 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -167,7 +167,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { TypeKind::Enum(..) | TypeKind::TypeParam | TypeKind::UnresolvedTypeRef(..) | - TypeKind::BlockPointer | TypeKind::Reference(..) | TypeKind::ObjCInterface(..) | TypeKind::ObjCId | @@ -241,7 +240,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { if self.cannot_derive_hash.contains(&t.into()) { trace!( " aliases and type refs to T which cannot derive \ diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs index 23d55c13..c643a90b 100644 --- a/src/ir/analysis/derive_partialeq_or_partialord.rs +++ b/src/ir/analysis/derive_partialeq_or_partialord.rs @@ -43,7 +43,7 @@ use std::collections::hash_map::Entry; pub struct CannotDerivePartialEqOrPartialOrd<'ctx> { ctx: &'ctx BindgenContext, - // The incremental result of this analysis's computation. + // The incremental result of this analysis's computation. // Contains information whether particular item can derive `PartialEq`/`PartialOrd`. can_derive_partialeq_or_partialord: HashMap<ItemId, CanDerive>, @@ -158,7 +158,6 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { TypeKind::Enum(..) | TypeKind::TypeParam | TypeKind::UnresolvedTypeRef(..) | - TypeKind::BlockPointer | TypeKind::Reference(..) | TypeKind::ObjCInterface(..) | TypeKind::ObjCId | @@ -281,6 +280,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { TypeKind::ResolvedTypeRef(..) | TypeKind::TemplateAlias(..) | TypeKind::Alias(..) | + TypeKind::BlockPointer(..) | TypeKind::TemplateInstantiation(..) => { return self.constrain_join(item); } diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 53e6a491..92bbe36c 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -122,7 +122,6 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { TypeKind::Function(..) | TypeKind::Enum(..) | TypeKind::Reference(..) | - TypeKind::BlockPointer | TypeKind::TypeParam | TypeKind::Opaque | TypeKind::Pointer(..) | @@ -159,7 +158,8 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { if self.has_float.contains(&t.into()) { trace!(" aliases and type refs to T which have float \ also have float"); diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index b7afe043..98288d3c 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -135,7 +135,6 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::Function(..) | TypeKind::Enum(..) | TypeKind::Reference(..) | - TypeKind::BlockPointer | TypeKind::TypeParam | TypeKind::Opaque | TypeKind::Pointer(..) | @@ -166,7 +165,8 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { + TypeKind::Alias(t) | + TypeKind::BlockPointer(t) => { if self.has_type_parameter_in_array.contains(&t.into()) { trace!( " aliases and type refs to T which have array \ diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs index e49b2570..9c074355 100644 --- a/src/ir/analysis/sizedness.rs +++ b/src/ir/analysis/sizedness.rs @@ -261,7 +261,6 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> { TypeKind::Enum(..) | TypeKind::Reference(..) | TypeKind::NullPtr | - TypeKind::BlockPointer | TypeKind::ObjCId | TypeKind::ObjCSel | TypeKind::Pointer(..) => { @@ -276,6 +275,7 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> { TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) | + TypeKind::BlockPointer(t) | TypeKind::ResolvedTypeRef(t) => { trace!(" aliases and type refs forward to their inner type"); self.forward(t, id) diff --git a/src/ir/ty.rs b/src/ir/ty.rs index ab39c19a..13153429 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -155,7 +155,6 @@ impl Type { TypeKind::Array(..) | TypeKind::Reference(..) | TypeKind::Pointer(..) | - TypeKind::BlockPointer | TypeKind::Int(..) | TypeKind::Float(..) | TypeKind::TypeParam => true, @@ -244,8 +243,7 @@ impl Type { TypeKind::Comp(ref ci) => ci.layout(ctx), // FIXME(emilio): This is a hack for anonymous union templates. // Use the actual pointer size! - TypeKind::Pointer(..) | - TypeKind::BlockPointer => { + TypeKind::Pointer(..) => { Some(Layout::new( ctx.target_pointer_size(), ctx.target_pointer_size(), @@ -339,7 +337,6 @@ impl Type { TypeKind::Reference(..) | TypeKind::Void | TypeKind::NullPtr | - TypeKind::BlockPointer | TypeKind::Pointer(..) | TypeKind::ObjCId | TypeKind::ObjCSel | @@ -347,6 +344,7 @@ impl Type { TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(inner) | + TypeKind::BlockPointer(inner) | TypeKind::TemplateAlias(inner, _) => { ctx.resolve_type(inner).safe_canonical_type(ctx) } @@ -485,7 +483,7 @@ impl TypeKind { TypeKind::Function(..) => "Function", TypeKind::Enum(..) => "Enum", TypeKind::Pointer(..) => "Pointer", - TypeKind::BlockPointer => "BlockPointer", + TypeKind::BlockPointer(..) => "BlockPointer", TypeKind::Reference(..) => "Reference", TypeKind::TemplateInstantiation(..) => "TemplateInstantiation", TypeKind::UnresolvedTypeRef(..) => "UnresolvedTypeRef", @@ -579,7 +577,7 @@ impl TemplateParameters for TypeKind { TypeKind::Function(_) | TypeKind::Enum(_) | TypeKind::Pointer(_) | - TypeKind::BlockPointer | + TypeKind::BlockPointer(_) | TypeKind::Reference(_) | TypeKind::UnresolvedTypeRef(..) | TypeKind::TypeParam | @@ -655,7 +653,7 @@ pub enum TypeKind { Pointer(TypeId), /// A pointer to an Apple block. - BlockPointer, + BlockPointer(TypeId), /// A reference to a type, as in: int& foo(). Reference(TypeId), @@ -1086,7 +1084,12 @@ impl Type { Item::from_ty_or_ref(pointee, location, None, ctx); TypeKind::Pointer(inner) } - CXType_BlockPointer => TypeKind::BlockPointer, + CXType_BlockPointer => { + let pointee = ty.pointee_type().expect("Not valid Type?"); + let inner = + Item::from_ty_or_ref(pointee, location, None, ctx); + TypeKind::BlockPointer(inner) + }, // XXX: RValueReference is most likely wrong, but I don't think we // can even add bindings for that, so huh. CXType_RValueReference | @@ -1232,6 +1235,7 @@ impl Trace for Type { TypeKind::Reference(inner) | TypeKind::Array(inner, _) | TypeKind::Vector(inner, _) | + TypeKind::BlockPointer(inner) | TypeKind::Alias(inner) | TypeKind::ResolvedTypeRef(inner) => { tracer.visit_kind(inner.into(), EdgeKind::TypeReference); @@ -1273,8 +1277,7 @@ impl Trace for Type { TypeKind::Float(_) | TypeKind::Complex(_) | TypeKind::ObjCId | - TypeKind::ObjCSel | - TypeKind::BlockPointer => {} + TypeKind::ObjCSel => {} } } } @@ -373,6 +373,10 @@ impl Builder { output_vector.push("--objc-extern-crate".into()); } + if self.options.block_extern_crate { + output_vector.push("--block-extern-crate".into()); + } + if self.options.builtins { output_vector.push("--builtins".into()); } @@ -700,6 +704,13 @@ impl Builder { self } + /// Generate `#[macro_use] extern crate block;` instead of `use block;` + /// in the prologue of the files generated from apple block files + pub fn block_extern_crate(mut self, doit: bool) -> Self { + self.options.block_extern_crate = doit; + self + } + /// Whether to use the clang-provided name mangling. This is true by default /// and probably needed for C++ features. /// @@ -1454,6 +1465,10 @@ struct BindgenOptions { /// generate '#[macro_use] extern crate objc;' objc_extern_crate: bool, + /// Instead of emitting 'use block;' to files generated from objective c files, + /// generate '#[macro_use] extern crate block;' + block_extern_crate: bool, + /// Whether to use the clang-provided name mangling. This is true and /// probably needed for C++ features. /// @@ -1579,6 +1594,7 @@ impl Default for BindgenOptions { generate_inline_functions: false, whitelist_recursively: true, objc_extern_crate: false, + block_extern_crate: false, enable_mangling: true, prepend_enum_name: true, time_phases: false, diff --git a/src/options.rs b/src/options.rs index 61f4f766..f72f060b 100644 --- a/src/options.rs +++ b/src/options.rs @@ -132,6 +132,9 @@ where Arg::with_name("objc-extern-crate") .long("objc-extern-crate") .help("Use extern crate instead of use for objc."), + Arg::with_name("block-extern-crate") + .long("block-extern-crate") + .help("Use extern crate instead of use for block."), Arg::with_name("distrust-clang-mangling") .long("distrust-clang-mangling") .help("Do not trust the libclang-provided mangling"), @@ -493,6 +496,10 @@ where builder = builder.objc_extern_crate(true); } + if matches.is_present("block-extern-crate") { + builder = builder.block_extern_crate(true); + } + if let Some(opaque_types) = matches.values_of("opaque-type") { for ty in opaque_types { builder = builder.opaque_type(ty); |