@@ -13,6 +13,7 @@ use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
13
13
use ir:: item_kind:: ItemKind ;
14
14
use ir:: layout:: Layout ;
15
15
use ir:: module:: Module ;
16
+ use ir:: objc:: ObjCInterface ;
16
17
use ir:: ty:: { Type , TypeKind } ;
17
18
use ir:: type_collector:: ItemSet ;
18
19
use ir:: var:: Var ;
@@ -87,6 +88,9 @@ struct CodegenResult<'a> {
87
88
/// Whether an incomplete array has been generated at least once.
88
89
saw_incomplete_array : bool ,
89
90
91
+ /// Whether Objective C types have been seen at least once.
92
+ saw_objc : bool ,
93
+
90
94
items_seen : HashSet < ItemId > ,
91
95
/// The set of generated function/var names, needed because in C/C++ is
92
96
/// legal to do something like:
@@ -119,6 +123,7 @@ impl<'a> CodegenResult<'a> {
119
123
items : vec ! [ ] ,
120
124
saw_union : false ,
121
125
saw_incomplete_array : false ,
126
+ saw_objc : false ,
122
127
codegen_id : codegen_id,
123
128
items_seen : Default :: default ( ) ,
124
129
functions_seen : Default :: default ( ) ,
@@ -140,6 +145,10 @@ impl<'a> CodegenResult<'a> {
140
145
self . saw_incomplete_array = true ;
141
146
}
142
147
148
+ fn saw_objc ( & mut self ) {
149
+ self . saw_objc = true ;
150
+ }
151
+
143
152
fn seen ( & self , item : ItemId ) -> bool {
144
153
self . items_seen . contains ( & item)
145
154
}
@@ -184,6 +193,7 @@ impl<'a> CodegenResult<'a> {
184
193
185
194
self . saw_union |= new. saw_union ;
186
195
self . saw_incomplete_array |= new. saw_incomplete_array ;
196
+ self . saw_objc |= new. saw_objc ;
187
197
188
198
new. items
189
199
}
@@ -359,6 +369,9 @@ impl CodeGenerator for Module {
359
369
if ctx. need_bindegen_complex_type ( ) {
360
370
utils:: prepend_complex_type ( ctx, & mut * result) ;
361
371
}
372
+ if result. saw_objc {
373
+ utils:: prepend_objc_header ( ctx, & mut * result) ;
374
+ }
362
375
}
363
376
} ;
364
377
@@ -603,6 +616,9 @@ impl CodeGenerator for Type {
603
616
TypeKind :: Enum ( ref ei) => {
604
617
ei. codegen ( ctx, result, whitelisted_items, item)
605
618
}
619
+ TypeKind :: ObjCInterface ( ref interface) => {
620
+ interface. codegen ( ctx, result, whitelisted_items, item)
621
+ }
606
622
ref u @ TypeKind :: UnresolvedTypeRef ( ..) => {
607
623
unreachable ! ( "Should have been resolved after parsing {:?}!" , u)
608
624
}
@@ -2090,6 +2106,10 @@ impl ToRustTy for Type {
2090
2106
let ident = ctx. rust_ident ( & name) ;
2091
2107
quote_ty ! ( ctx. ext_cx( ) , $ident)
2092
2108
}
2109
+ TypeKind :: ObjCInterface ( ..) => {
2110
+ let ident = ctx. rust_ident ( "id" ) ;
2111
+ quote_ty ! ( ctx. ext_cx( ) , $ident)
2112
+ }
2093
2113
ref u @ TypeKind :: UnresolvedTypeRef ( ..) => {
2094
2114
unreachable ! ( "Should have been resolved after parsing {:?}!" , u)
2095
2115
}
@@ -2123,10 +2143,24 @@ impl ToRustTy for FunctionSig {
2123
2143
// the array type derivation.
2124
2144
//
2125
2145
// [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
2126
- let arg_ty = if let TypeKind :: Array ( t, _) = * arg_ty. canonical_type ( ctx) . kind ( ) {
2146
+
2147
+
2148
+ let arg_ty = match * arg_ty. canonical_type ( ctx) . kind ( ) {
2149
+ TypeKind :: Array ( t, _) => {
2127
2150
t. to_rust_ty ( ctx) . to_ptr ( arg_ty. is_const ( ) , ctx. span ( ) )
2151
+ } ,
2152
+ TypeKind :: Pointer ( inner) => {
2153
+ let inner = ctx. resolve_item ( inner) ;
2154
+ let inner_ty = inner. expect_type ( ) ;
2155
+ if let TypeKind :: ObjCInterface ( _) = * inner_ty. canonical_type ( ctx) . kind ( ) {
2156
+ aster:: ty:: TyBuilder :: new ( ) . id ( "id" )
2128
2157
} else {
2129
2158
arg_item. to_rust_ty ( ctx)
2159
+ }
2160
+ } ,
2161
+ _ => {
2162
+ arg_item. to_rust_ty ( ctx)
2163
+ }
2130
2164
} ;
2131
2165
2132
2166
let arg_name = match * name {
@@ -2242,6 +2276,90 @@ impl CodeGenerator for Function {
2242
2276
}
2243
2277
}
2244
2278
2279
+ impl CodeGenerator for ObjCInterface {
2280
+ type Extra = Item ;
2281
+ fn codegen < ' a > ( & self ,
2282
+ ctx : & BindgenContext ,
2283
+ result : & mut CodegenResult < ' a > ,
2284
+ _whitelisted_items : & ItemSet ,
2285
+ _: & Item ) {
2286
+
2287
+ let mut impl_items = vec ! [ ] ;
2288
+ let mut trait_items = vec ! [ ] ;
2289
+
2290
+ for method in & self . methods {
2291
+ let method_name = ctx. rust_ident ( & method. name ) ;
2292
+
2293
+ let body = quote_stmt ! ( ctx. ext_cx( ) , msg_send![ self , $method_name] )
2294
+ . unwrap ( ) ;
2295
+ let block = ast:: Block {
2296
+ stmts : vec ! [ body] ,
2297
+ id : ast:: DUMMY_NODE_ID ,
2298
+ rules : ast:: BlockCheckMode :: Default ,
2299
+ span : ctx. span ( ) ,
2300
+ } ;
2301
+
2302
+ let sig = aster:: AstBuilder :: new ( )
2303
+ . method_sig ( )
2304
+ . unsafe_ ( )
2305
+ . fn_decl ( )
2306
+ . self_ ( )
2307
+ . build ( ast:: SelfKind :: Value ( ast:: Mutability :: Immutable ) ) //ast::SelfKind::Region(None, ast::Mutability::Mutable))
2308
+ . build ( ast:: FunctionRetTy :: Default ( ctx. span ( ) ) ) ;
2309
+ let attrs = vec ! [ ] ;
2310
+
2311
+ let impl_item = ast:: ImplItem {
2312
+ id : ast:: DUMMY_NODE_ID ,
2313
+ ident : ctx. rust_ident ( & method. rust_name ) ,
2314
+ vis : ast:: Visibility :: Inherited , // Public,
2315
+ attrs : attrs. clone ( ) ,
2316
+ node : ast:: ImplItemKind :: Method ( sig. clone ( ) , P ( block) ) ,
2317
+ defaultness : ast:: Defaultness :: Final ,
2318
+ span : ctx. span ( ) ,
2319
+ } ;
2320
+
2321
+ let trait_item = ast:: TraitItem {
2322
+ id : ast:: DUMMY_NODE_ID ,
2323
+ ident : ctx. rust_ident ( & method. rust_name ) ,
2324
+ attrs : attrs,
2325
+ node : ast:: TraitItemKind :: Method ( sig, None ) ,
2326
+ span : ctx. span ( ) ,
2327
+ } ;
2328
+
2329
+ impl_items. push ( impl_item) ;
2330
+ trait_items. push ( trait_item)
2331
+ }
2332
+
2333
+
2334
+ let trait_block = aster:: AstBuilder :: new ( )
2335
+ . item ( )
2336
+ . pub_ ( )
2337
+ . trait_ ( & self . name )
2338
+ . with_items ( trait_items)
2339
+ . build ( ) ;
2340
+
2341
+ let ty_for_impl = aster:: AstBuilder :: new ( )
2342
+ . ty ( )
2343
+ . path ( )
2344
+ . id ( ctx. rust_ident ( "id" ) )
2345
+ . build ( ) ;
2346
+ let impl_block = aster:: AstBuilder :: new ( )
2347
+ . item ( )
2348
+ . impl_ ( )
2349
+ . trait_ ( )
2350
+ . id ( & self . name )
2351
+ . build ( )
2352
+ . with_items ( impl_items)
2353
+ . build_ty ( ty_for_impl) ;
2354
+
2355
+ result. push ( trait_block) ;
2356
+ result. push ( impl_block) ;
2357
+ result. saw_objc ( ) ;
2358
+ }
2359
+ }
2360
+
2361
+
2362
+
2245
2363
pub fn codegen ( context : & mut BindgenContext ) -> Vec < P < ast:: Item > > {
2246
2364
context. gen ( |context| {
2247
2365
let counter = Cell :: new ( 0 ) ;
@@ -2275,6 +2393,38 @@ mod utils {
2275
2393
use syntax:: ast;
2276
2394
use syntax:: ptr:: P ;
2277
2395
2396
+
2397
+ pub fn prepend_objc_header ( ctx : & BindgenContext ,
2398
+ result : & mut Vec < P < ast:: Item > > ) {
2399
+
2400
+
2401
+ let use_objc;
2402
+
2403
+ if ctx. options ( ) . objc_extern_crate {
2404
+ use_objc = quote_item ! ( ctx. ext_cx( ) ,
2405
+ use objc;
2406
+ )
2407
+ . unwrap ( ) ;
2408
+ } else {
2409
+ use_objc = quote_item ! ( ctx. ext_cx( ) ,
2410
+ #[ macro_use]
2411
+ extern crate objc;
2412
+ )
2413
+ . unwrap ( ) ;
2414
+ }
2415
+
2416
+
2417
+ let id_type = quote_item ! ( ctx. ext_cx( ) ,
2418
+ #[ allow( non_camel_case_types) ]
2419
+ pub type id = * mut objc:: runtime:: Object ;
2420
+ )
2421
+ . unwrap ( ) ;
2422
+
2423
+ let items = vec ! [ use_objc, id_type] ;
2424
+ let old_items = mem:: replace ( result, items) ;
2425
+ result. extend ( old_items. into_iter ( ) ) ;
2426
+ }
2427
+
2278
2428
pub fn prepend_union_types ( ctx : & BindgenContext ,
2279
2429
result : & mut Vec < P < ast:: Item > > ) {
2280
2430
let prefix = ctx. trait_prefix ( ) ;
0 commit comments