@@ -12,6 +12,7 @@ use ir::layout::Layout;
12
12
13
13
use std:: ops;
14
14
use std:: mem;
15
+ use std:: collections:: BTreeSet ;
15
16
use std:: collections:: hash_map:: { HashMap , Entry } ;
16
17
17
18
use syntax:: abi:: Abi ;
@@ -489,26 +490,6 @@ impl<'a> Bitfield<'a> {
489
490
}
490
491
}
491
492
492
- fn type_for_bitfield_width ( ctx : & BindgenContext , width : u32 , is_arg : bool ) -> P < ast:: Ty > {
493
- let input_type = if width > 16 {
494
- "u32"
495
- } else if width > 8 {
496
- "u16"
497
- } else if width > 1 {
498
- "u8"
499
- } else {
500
- if is_arg {
501
- "bool"
502
- } else {
503
- "u8"
504
- }
505
- } ;
506
-
507
- let ident = ctx. rust_ident_raw ( input_type) ;
508
- quote_ty ! ( ctx. ext_cx( ) , $ident)
509
- }
510
-
511
-
512
493
fn codegen_fields ( self ,
513
494
ctx : & BindgenContext ,
514
495
fields : & mut Vec < ast:: StructField > ,
@@ -1400,14 +1381,130 @@ impl CodeGenerator for Function {
1400
1381
}
1401
1382
}
1402
1383
1384
+ type ItemSet = BTreeSet < ItemId > ;
1385
+
1386
+ trait TypeCollector {
1387
+ type Extra ;
1388
+
1389
+ fn collect_types ( & self ,
1390
+ context : & BindgenContext ,
1391
+ types : & mut ItemSet ,
1392
+ extra : & Self :: Extra ) ;
1393
+ }
1394
+
1395
+ impl TypeCollector for ItemId {
1396
+ type Extra = ( ) ;
1397
+
1398
+ fn collect_types ( & self ,
1399
+ context : & BindgenContext ,
1400
+ types : & mut ItemSet ,
1401
+ extra : & ( ) ) {
1402
+ context. resolve_item ( * self ) . collect_types ( context, types, extra) ;
1403
+ }
1404
+ }
1405
+
1406
+ impl TypeCollector for Item {
1407
+ type Extra = ( ) ;
1408
+
1409
+ fn collect_types ( & self ,
1410
+ context : & BindgenContext ,
1411
+ types : & mut ItemSet ,
1412
+ _extra : & ( ) ) {
1413
+ // NB: non-toplevel items are generated by their parents.
1414
+ if self . hidden ( context) || !self . is_toplevel ( context) || types. contains ( & self . id ( ) ) {
1415
+ return ;
1416
+ }
1417
+
1418
+ match * self . kind ( ) {
1419
+ ItemKind :: Type ( ref ty) => {
1420
+ types. insert ( self . id ( ) ) ;
1421
+ if !self . opaque ( context) {
1422
+ ty. collect_types ( context, types, self ) ;
1423
+ }
1424
+ }
1425
+ _ => { } , // FIXME.
1426
+ }
1427
+ }
1428
+ }
1429
+
1430
+ impl TypeCollector for Type {
1431
+ type Extra = Item ;
1432
+
1433
+ fn collect_types ( & self ,
1434
+ context : & BindgenContext ,
1435
+ types : & mut ItemSet ,
1436
+ item : & Item ) {
1437
+ match * self . kind ( ) {
1438
+ TypeKind :: Comp ( ref ci) => ci. collect_types ( context, types, item) ,
1439
+ TypeKind :: Alias ( _, ref inner) => inner. collect_types ( context, types, & ( ) ) ,
1440
+ _ => { } ,
1441
+ }
1442
+ }
1443
+ }
1444
+
1445
+ impl TypeCollector for CompInfo {
1446
+ type Extra = Item ;
1447
+
1448
+ fn collect_types ( & self ,
1449
+ context : & BindgenContext ,
1450
+ types : & mut ItemSet ,
1451
+ item : & Item ) {
1452
+ let applicable_template_args = item. applicable_template_args ( context) ;
1453
+ for arg in applicable_template_args {
1454
+ arg. collect_types ( context, types, & ( ) ) ;
1455
+ }
1456
+
1457
+ for base in self . base_members ( ) {
1458
+ base. collect_types ( context, types, & ( ) ) ;
1459
+ }
1460
+
1461
+ for field in self . fields ( ) {
1462
+ field. ty ( ) . collect_types ( context, types, & ( ) ) ;
1463
+ }
1464
+
1465
+ // FIXME(emilio): Methods, VTable?
1466
+ }
1467
+ }
1468
+
1403
1469
pub fn codegen ( context : & mut BindgenContext ) -> Vec < P < ast:: Item > > {
1404
1470
context. gen ( |context| {
1405
1471
let mut result = CodegenResult :: new ( ) ;
1406
- for ( _item_id, item) in context. items ( ) {
1407
- // Non-toplevel item parents are the responsible one for generating
1408
- // them.
1409
- if item. is_toplevel ( context) {
1410
- item. codegen ( context, & mut result, & ( ) ) ;
1472
+
1473
+ debug ! ( "codegen: {:?}" , context. options( ) ) ;
1474
+
1475
+ // If the whitelisted types set is empty, just generate everything.
1476
+ if context. options ( ) . whitelisted_types . is_empty ( ) {
1477
+ for ( _item_id, item) in context. items ( ) {
1478
+ // Non-toplevel item parents are the responsible one for generating
1479
+ // them.
1480
+ if item. is_toplevel ( context) {
1481
+ item. codegen ( context, & mut result, & ( ) ) ;
1482
+ }
1483
+ }
1484
+ } else {
1485
+ // Recursively collect all the types dependent on the whitelisted
1486
+ // types, then generate them.
1487
+ //
1488
+ // FIXME(emilio): This pass is probably slow, but it can't be faster
1489
+ // than docopt anyway :)
1490
+ let mut types = ItemSet :: new ( ) ;
1491
+ for ( _item_id, item) in context. items ( ) {
1492
+ // FIXME(emilio): This only works for types, but we need to
1493
+ // eventually come with a coherent history for functions...
1494
+ //
1495
+ // Whitelisting any type touched by a function seems overkill,
1496
+ // maybe another pass whitelisting functions that only contain
1497
+ // whitelisted types?
1498
+ if item. kind ( ) . is_type ( ) && item. is_toplevel ( context) {
1499
+ let name = item. canonical_name ( context) ;
1500
+ if context. options ( ) . whitelisted_types . contains ( & name) {
1501
+ item. collect_types ( context, & mut types, & ( ) ) ;
1502
+ }
1503
+ }
1504
+ }
1505
+
1506
+ for item_id in types. iter ( ) {
1507
+ context. resolve_item ( * item_id) . codegen ( context, & mut result, & ( ) ) ;
1411
1508
}
1412
1509
}
1413
1510
let saw_union = result. saw_union ;
0 commit comments