Skip to content

generate type alias for the block type #1378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
Expand Down
4 changes: 2 additions & 2 deletions src/codegen/impl_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ impl<'a> ImplDebug<'a> for Item {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::BlockPointer |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
Expand Down Expand Up @@ -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)
}
Expand Down
4 changes: 2 additions & 2 deletions src/codegen/impl_partialeq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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)
}
Expand Down
101 changes: 85 additions & 16 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -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(),
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -293,7 +302,6 @@ impl AppendImplicitTemplateParams for quote::Tokens {
TypeKind::Opaque |
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::BlockPointer |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::TemplateInstantiation(..) => return,
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -597,7 +608,6 @@ impl CodeGenerator for Type {
TypeKind::Array(..) |
TypeKind::Vector(..) |
TypeKind::Pointer(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::Function(..) |
TypeKind::ResolvedTypeRef(..) |
Expand All @@ -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) => {
Expand Down Expand Up @@ -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)
Expand All @@ -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();
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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)| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ty.to_rust_ty_or_opaque(ctx, &()) would do just fine here, no need to try_to_rust_ty, unless you have a test-case in which it makes a difference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

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>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late to the party, but if there is a single arg then this expands to Block<(arg), ret> which parses the same as Block<arg, ret>. What's needed here is Block<(arg,), ret> so that args is a single-element tuple.

Copy link
Contributor Author

@flier flier Feb 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree, this should be a bug, I have submitted a PR #1519 for this, thanks very much!

}
}
}
4 changes: 2 additions & 2 deletions src/ir/analysis/derive_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::TypeParam |
TypeKind::BlockPointer |
TypeKind::Pointer(..) |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::ObjCInterface(..) |
Expand Down Expand Up @@ -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!(
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/derive_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::Vector(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::ObjCInterface(..) |
Expand Down Expand Up @@ -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 \
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/derive_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
TypeKind::Reference(..) |
TypeKind::NullPtr |
TypeKind::Pointer(..) |
TypeKind::BlockPointer |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::ObjCInterface(..) |
Expand Down Expand Up @@ -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 \
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/derive_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
TypeKind::Enum(..) |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
Expand Down Expand Up @@ -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 \
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/derive_partialeq_or_partialord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,

Expand Down Expand Up @@ -158,7 +158,6 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::Enum(..) |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
Expand Down Expand Up @@ -281,6 +280,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::ResolvedTypeRef(..) |
TypeKind::TemplateAlias(..) |
TypeKind::Alias(..) |
TypeKind::BlockPointer(..) |
TypeKind::TemplateInstantiation(..) => {
return self.constrain_join(item);
}
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/has_float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::Opaque |
TypeKind::Pointer(..) |
Expand Down Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/has_type_param_in_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::Opaque |
TypeKind::Pointer(..) |
Expand Down Expand Up @@ -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 \
Expand Down
2 changes: 1 addition & 1 deletion src/ir/analysis/sizedness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> {
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::NullPtr |
TypeKind::BlockPointer |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::Pointer(..) => {
Expand All @@ -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)
Expand Down
Loading