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