@@ -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
@@ -622,6 +635,9 @@ impl CodeGenerator for Type {
622
635
TypeKind :: Enum ( ref ei) => {
623
636
ei. codegen ( ctx, result, whitelisted_items, item)
624
637
}
638
+ TypeKind :: ObjCInterface ( ref interface) => {
639
+ interface. codegen ( ctx, result, whitelisted_items, item)
640
+ }
625
641
ref u @ TypeKind :: UnresolvedTypeRef ( ..) => {
626
642
unreachable ! ( "Should have been resolved after parsing {:?}!" , u)
627
643
}
@@ -2109,6 +2125,10 @@ impl ToRustTy for Type {
2109
2125
let ident = ctx. rust_ident ( & name) ;
2110
2126
quote_ty ! ( ctx. ext_cx( ) , $ident)
2111
2127
}
2128
+ TypeKind :: ObjCInterface ( ..) => {
2129
+ let ident = ctx. rust_ident ( "id" ) ;
2130
+ quote_ty ! ( ctx. ext_cx( ) , $ident)
2131
+ }
2112
2132
ref u @ TypeKind :: UnresolvedTypeRef ( ..) => {
2113
2133
unreachable ! ( "Should have been resolved after parsing {:?}!" , u)
2114
2134
}
@@ -2142,10 +2162,24 @@ impl ToRustTy for FunctionSig {
2142
2162
// the array type derivation.
2143
2163
//
2144
2164
// [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
2145
- let arg_ty = if let TypeKind :: Array ( t, _) = * arg_ty. canonical_type ( ctx) . kind ( ) {
2165
+
2166
+
2167
+ let arg_ty = match * arg_ty. canonical_type ( ctx) . kind ( ) {
2168
+ TypeKind :: Array ( t, _) => {
2146
2169
t. to_rust_ty ( ctx) . to_ptr ( arg_ty. is_const ( ) , ctx. span ( ) )
2170
+ } ,
2171
+ TypeKind :: Pointer ( inner) => {
2172
+ let inner = ctx. resolve_item ( inner) ;
2173
+ let inner_ty = inner. expect_type ( ) ;
2174
+ if let TypeKind :: ObjCInterface ( _) = * inner_ty. canonical_type ( ctx) . kind ( ) {
2175
+ aster:: ty:: TyBuilder :: new ( ) . id ( "id" )
2147
2176
} else {
2148
2177
arg_item. to_rust_ty ( ctx)
2178
+ }
2179
+ } ,
2180
+ _ => {
2181
+ arg_item. to_rust_ty ( ctx)
2182
+ }
2149
2183
} ;
2150
2184
2151
2185
let arg_name = match * name {
@@ -2261,6 +2295,90 @@ impl CodeGenerator for Function {
2261
2295
}
2262
2296
}
2263
2297
2298
+ impl CodeGenerator for ObjCInterface {
2299
+ type Extra = Item ;
2300
+ fn codegen < ' a > ( & self ,
2301
+ ctx : & BindgenContext ,
2302
+ result : & mut CodegenResult < ' a > ,
2303
+ _whitelisted_items : & ItemSet ,
2304
+ _: & Item ) {
2305
+
2306
+ let mut impl_items = vec ! [ ] ;
2307
+ let mut trait_items = vec ! [ ] ;
2308
+
2309
+ for method in & self . methods {
2310
+ let method_name = ctx. rust_ident ( & method. name ) ;
2311
+
2312
+ let body = quote_stmt ! ( ctx. ext_cx( ) , msg_send![ self , $method_name] )
2313
+ . unwrap ( ) ;
2314
+ let block = ast:: Block {
2315
+ stmts : vec ! [ body] ,
2316
+ id : ast:: DUMMY_NODE_ID ,
2317
+ rules : ast:: BlockCheckMode :: Default ,
2318
+ span : ctx. span ( ) ,
2319
+ } ;
2320
+
2321
+ let sig = aster:: AstBuilder :: new ( )
2322
+ . method_sig ( )
2323
+ . unsafe_ ( )
2324
+ . fn_decl ( )
2325
+ . self_ ( )
2326
+ . build ( ast:: SelfKind :: Value ( ast:: Mutability :: Immutable ) ) //ast::SelfKind::Region(None, ast::Mutability::Mutable))
2327
+ . build ( ast:: FunctionRetTy :: Default ( ctx. span ( ) ) ) ;
2328
+ let attrs = vec ! [ ] ;
2329
+
2330
+ let impl_item = ast:: ImplItem {
2331
+ id : ast:: DUMMY_NODE_ID ,
2332
+ ident : ctx. rust_ident ( & method. rust_name ) ,
2333
+ vis : ast:: Visibility :: Inherited , // Public,
2334
+ attrs : attrs. clone ( ) ,
2335
+ node : ast:: ImplItemKind :: Method ( sig. clone ( ) , P ( block) ) ,
2336
+ defaultness : ast:: Defaultness :: Final ,
2337
+ span : ctx. span ( ) ,
2338
+ } ;
2339
+
2340
+ let trait_item = ast:: TraitItem {
2341
+ id : ast:: DUMMY_NODE_ID ,
2342
+ ident : ctx. rust_ident ( & method. rust_name ) ,
2343
+ attrs : attrs,
2344
+ node : ast:: TraitItemKind :: Method ( sig, None ) ,
2345
+ span : ctx. span ( ) ,
2346
+ } ;
2347
+
2348
+ impl_items. push ( impl_item) ;
2349
+ trait_items. push ( trait_item)
2350
+ }
2351
+
2352
+
2353
+ let trait_block = aster:: AstBuilder :: new ( )
2354
+ . item ( )
2355
+ . pub_ ( )
2356
+ . trait_ ( & self . name )
2357
+ . with_items ( trait_items)
2358
+ . build ( ) ;
2359
+
2360
+ let ty_for_impl = aster:: AstBuilder :: new ( )
2361
+ . ty ( )
2362
+ . path ( )
2363
+ . id ( ctx. rust_ident ( "id" ) )
2364
+ . build ( ) ;
2365
+ let impl_block = aster:: AstBuilder :: new ( )
2366
+ . item ( )
2367
+ . impl_ ( )
2368
+ . trait_ ( )
2369
+ . id ( & self . name )
2370
+ . build ( )
2371
+ . with_items ( impl_items)
2372
+ . build_ty ( ty_for_impl) ;
2373
+
2374
+ result. push ( trait_block) ;
2375
+ result. push ( impl_block) ;
2376
+ result. saw_objc ( ) ;
2377
+ }
2378
+ }
2379
+
2380
+
2381
+
2264
2382
pub fn codegen ( context : & mut BindgenContext ) -> Vec < P < ast:: Item > > {
2265
2383
context. gen ( |context| {
2266
2384
let counter = Cell :: new ( 0 ) ;
@@ -2294,6 +2412,38 @@ mod utils {
2294
2412
use syntax:: ast;
2295
2413
use syntax:: ptr:: P ;
2296
2414
2415
+
2416
+ pub fn prepend_objc_header ( ctx : & BindgenContext ,
2417
+ result : & mut Vec < P < ast:: Item > > ) {
2418
+
2419
+
2420
+ let use_objc;
2421
+
2422
+ if ctx. options ( ) . objc_extern_crate {
2423
+ use_objc = quote_item ! ( ctx. ext_cx( ) ,
2424
+ use objc;
2425
+ )
2426
+ . unwrap ( ) ;
2427
+ } else {
2428
+ use_objc = quote_item ! ( ctx. ext_cx( ) ,
2429
+ #[ macro_use]
2430
+ extern crate objc;
2431
+ )
2432
+ . unwrap ( ) ;
2433
+ }
2434
+
2435
+
2436
+ let id_type = quote_item ! ( ctx. ext_cx( ) ,
2437
+ #[ allow( non_camel_case_types) ]
2438
+ pub type id = * mut objc:: runtime:: Object ;
2439
+ )
2440
+ . unwrap ( ) ;
2441
+
2442
+ let items = vec ! [ use_objc, id_type] ;
2443
+ let old_items = mem:: replace ( result, items) ;
2444
+ result. extend ( old_items. into_iter ( ) ) ;
2445
+ }
2446
+
2297
2447
pub fn prepend_union_types ( ctx : & BindgenContext ,
2298
2448
result : & mut Vec < P < ast:: Item > > ) {
2299
2449
let prefix = ctx. trait_prefix ( ) ;
0 commit comments