@@ -103,6 +103,9 @@ struct CodegenResult<'a> {
103
103
/// Whether Objective C types have been seen at least once.
104
104
saw_objc : bool ,
105
105
106
+ /// Whether Apple block types have been seen at least once.
107
+ saw_block : bool ,
108
+
106
109
/// Whether a bitfield allocation unit has been seen at least once.
107
110
saw_bitfield_unit : bool ,
108
111
@@ -140,6 +143,7 @@ impl<'a> CodegenResult<'a> {
140
143
saw_bindgen_union : false ,
141
144
saw_incomplete_array : false ,
142
145
saw_objc : false ,
146
+ saw_block : false ,
143
147
saw_bitfield_unit : false ,
144
148
codegen_id : codegen_id,
145
149
items_seen : Default :: default ( ) ,
@@ -166,6 +170,10 @@ impl<'a> CodegenResult<'a> {
166
170
self . saw_objc = true ;
167
171
}
168
172
173
+ fn saw_block ( & mut self ) {
174
+ self . saw_block = true ;
175
+ }
176
+
169
177
fn saw_bitfield_unit ( & mut self ) {
170
178
self . saw_bitfield_unit = true ;
171
179
}
@@ -215,6 +223,7 @@ impl<'a> CodegenResult<'a> {
215
223
self . saw_union |= new. saw_union ;
216
224
self . saw_incomplete_array |= new. saw_incomplete_array ;
217
225
self . saw_objc |= new. saw_objc ;
226
+ self . saw_block |= new. saw_block ;
218
227
self . saw_bitfield_unit |= new. saw_bitfield_unit ;
219
228
220
229
new. items
@@ -293,7 +302,6 @@ impl AppendImplicitTemplateParams for quote::Tokens {
293
302
TypeKind :: Opaque |
294
303
TypeKind :: Function ( ..) |
295
304
TypeKind :: Enum ( ..) |
296
- TypeKind :: BlockPointer |
297
305
TypeKind :: ObjCId |
298
306
TypeKind :: ObjCSel |
299
307
TypeKind :: TemplateInstantiation ( ..) => return ,
@@ -394,6 +402,9 @@ impl CodeGenerator for Module {
394
402
}
395
403
396
404
if item. id ( ) == ctx. root_module ( ) {
405
+ if result. saw_block {
406
+ utils:: prepend_block_header ( ctx, & mut * result) ;
407
+ }
397
408
if result. saw_bindgen_union {
398
409
utils:: prepend_union_types ( ctx, & mut * result) ;
399
410
}
@@ -597,7 +608,6 @@ impl CodeGenerator for Type {
597
608
TypeKind :: Array ( ..) |
598
609
TypeKind :: Vector ( ..) |
599
610
TypeKind :: Pointer ( ..) |
600
- TypeKind :: BlockPointer |
601
611
TypeKind :: Reference ( ..) |
602
612
TypeKind :: Function ( ..) |
603
613
TypeKind :: ResolvedTypeRef ( ..) |
@@ -610,6 +620,35 @@ impl CodeGenerator for Type {
610
620
TypeKind :: TemplateInstantiation ( ref inst) => {
611
621
inst. codegen ( ctx, result, item)
612
622
}
623
+ TypeKind :: BlockPointer ( inner) => {
624
+ let inner_item = inner. into_resolver ( )
625
+ . through_type_refs ( )
626
+ . resolve ( ctx) ;
627
+ let name = item. canonical_name ( ctx) ;
628
+
629
+ let inner_rust_type = {
630
+ if let TypeKind :: Function ( fnsig) = inner_item. kind ( ) . expect_type ( ) . kind ( ) {
631
+ utils:: fnsig_block ( ctx, fnsig)
632
+ } else {
633
+ panic ! ( "invalid block typedef: {:?}" , inner_item)
634
+ }
635
+ } ;
636
+
637
+ let rust_name = ctx. rust_ident ( & name) ;
638
+
639
+ let mut tokens = if let Some ( comment) = item. comment ( ctx) {
640
+ attributes:: doc ( comment)
641
+ } else {
642
+ quote ! { }
643
+ } ;
644
+
645
+ tokens. append_all ( quote ! {
646
+ pub type #rust_name = #inner_rust_type ;
647
+ } ) ;
648
+
649
+ result. push ( tokens) ;
650
+ result. saw_block ( ) ;
651
+ }
613
652
TypeKind :: Comp ( ref ci) => ci. codegen ( ctx, result, item) ,
614
653
TypeKind :: TemplateAlias ( inner, _) |
615
654
TypeKind :: Alias ( inner) => {
@@ -3071,20 +3110,16 @@ impl TryToRustTy for Type {
3071
3110
}
3072
3111
TypeKind :: ResolvedTypeRef ( inner) => inner. try_to_rust_ty ( ctx, & ( ) ) ,
3073
3112
TypeKind :: TemplateAlias ( ..) |
3074
- TypeKind :: Alias ( ..) => {
3113
+ TypeKind :: Alias ( ..) |
3114
+ TypeKind :: BlockPointer ( ..) => {
3075
3115
let template_params = item. used_template_params ( ctx)
3076
3116
. into_iter ( )
3077
3117
. filter ( |param| param. is_template_param ( ctx, & ( ) ) )
3078
3118
. collect :: < Vec < _ > > ( ) ;
3079
3119
3080
- let spelling = self . name ( ) . expect ( "Unnamed alias?" ) ;
3081
3120
if item. is_opaque ( ctx, & ( ) ) && !template_params. is_empty ( ) {
3082
3121
self . try_to_opaque ( ctx, item)
3083
- } else if let Some ( ty) = utils:: type_from_named (
3084
- ctx,
3085
- spelling,
3086
- )
3087
- {
3122
+ } else if let Some ( ty) = self . name ( ) . and_then ( |name| utils:: type_from_named ( ctx, name) ) {
3088
3123
Ok ( ty)
3089
3124
} else {
3090
3125
utils:: build_path ( item, ctx)
@@ -3101,13 +3136,6 @@ impl TryToRustTy for Type {
3101
3136
utils:: build_path ( item, ctx)
3102
3137
}
3103
3138
TypeKind :: Opaque => self . try_to_opaque ( ctx, item) ,
3104
- TypeKind :: BlockPointer => {
3105
- let void = raw_type ( ctx, "c_void" ) ;
3106
- Ok ( void. to_ptr (
3107
- /* is_const = */
3108
- false
3109
- ) )
3110
- }
3111
3139
TypeKind :: Pointer ( inner) |
3112
3140
TypeKind :: Reference ( inner) => {
3113
3141
let is_const = ctx. resolve_type ( inner) . is_const ( ) ;
@@ -3560,6 +3588,25 @@ mod utils {
3560
3588
result. extend ( old_items. into_iter ( ) ) ;
3561
3589
}
3562
3590
3591
+ pub fn prepend_block_header (
3592
+ ctx : & BindgenContext ,
3593
+ result : & mut Vec < quote:: Tokens > ,
3594
+ ) {
3595
+ let use_block = if ctx. options ( ) . block_extern_crate {
3596
+ quote ! {
3597
+ extern crate block;
3598
+ }
3599
+ } else {
3600
+ quote ! {
3601
+ use block;
3602
+ }
3603
+ } ;
3604
+
3605
+ let items = vec ! [ use_block] ;
3606
+ let old_items = mem:: replace ( result, items) ;
3607
+ result. extend ( old_items. into_iter ( ) ) ;
3608
+ }
3609
+
3563
3610
pub fn prepend_union_types (
3564
3611
ctx : & BindgenContext ,
3565
3612
result : & mut Vec < quote:: Tokens > ,
@@ -3871,4 +3918,26 @@ mod utils {
3871
3918
3872
3919
args
3873
3920
}
3921
+
3922
+ pub fn fnsig_block (
3923
+ ctx : & BindgenContext ,
3924
+ sig : & FunctionSig ,
3925
+ ) -> quote:: Tokens {
3926
+ let args = sig. argument_types ( ) . iter ( ) . map ( |& ( _, ty) | {
3927
+ let arg_item = ctx. resolve_item ( ty) ;
3928
+
3929
+ arg_item. to_rust_ty_or_opaque ( ctx, & ( ) )
3930
+ } ) ;
3931
+
3932
+ let return_item = ctx. resolve_item ( sig. return_type ( ) ) ;
3933
+ let ret_ty = if let TypeKind :: Void = * return_item. kind ( ) . expect_type ( ) . kind ( ) {
3934
+ quote ! { ( ) }
3935
+ } else {
3936
+ return_item. to_rust_ty_or_opaque ( ctx, & ( ) )
3937
+ } ;
3938
+
3939
+ quote ! {
3940
+ * const :: block:: Block <( #( #args) , * ) , #ret_ty>
3941
+ }
3942
+ }
3874
3943
}
0 commit comments