@@ -19,6 +19,7 @@ use ir::var::Var;
19
19
use self :: helpers:: { BlobTyBuilder , attributes} ;
20
20
21
21
use std:: borrow:: Cow ;
22
+ use std:: cell:: Cell ;
22
23
use std:: collections:: HashSet ;
23
24
use std:: collections:: hash_map:: { Entry , HashMap } ;
24
25
use std:: fmt:: Write ;
@@ -59,9 +60,16 @@ fn root_import(ctx: &BindgenContext, module: &Item) -> P<ast::Item> {
59
60
quote_item ! ( ctx. ext_cx( ) , #[ allow( unused_imports) ] $use_root) . unwrap ( )
60
61
}
61
62
62
- struct CodegenResult {
63
+ struct CodegenResult < ' a > {
63
64
items : Vec < P < ast:: Item > > ,
65
+
66
+ /// A monotonic counter used to add stable unique id's to stuff that doesn't
67
+ /// need to be referenced by anything.
68
+ codegen_id : & ' a Cell < usize > ,
69
+
70
+ /// Whether an union has been generated at least once.
64
71
saw_union : bool ,
72
+
65
73
items_seen : HashSet < ItemId > ,
66
74
/// The set of generated function/var names, needed because in C/C++ is
67
75
/// legal to do something like:
@@ -88,18 +96,24 @@ struct CodegenResult {
88
96
overload_counters : HashMap < String , u32 > ,
89
97
}
90
98
91
- impl CodegenResult {
92
- fn new ( ) -> Self {
99
+ impl < ' a > CodegenResult < ' a > {
100
+ fn new ( codegen_id : & ' a Cell < usize > ) -> Self {
93
101
CodegenResult {
94
102
items : vec ! [ ] ,
95
103
saw_union : false ,
104
+ codegen_id : codegen_id,
96
105
items_seen : Default :: default ( ) ,
97
106
functions_seen : Default :: default ( ) ,
98
107
vars_seen : Default :: default ( ) ,
99
108
overload_counters : Default :: default ( ) ,
100
109
}
101
110
}
102
111
112
+ fn next_id ( & mut self ) -> usize {
113
+ self . codegen_id . set ( self . codegen_id . get ( ) + 1 ) ;
114
+ self . codegen_id . get ( )
115
+ }
116
+
103
117
fn saw_union ( & mut self ) {
104
118
self . saw_union = true ;
105
119
}
@@ -142,7 +156,7 @@ impl CodegenResult {
142
156
fn inner < F > ( & mut self , cb : F ) -> Vec < P < ast:: Item > >
143
157
where F : FnOnce ( & mut Self ) ,
144
158
{
145
- let mut new = Self :: new ( ) ;
159
+ let mut new = Self :: new ( self . codegen_id ) ;
146
160
147
161
cb ( & mut new) ;
148
162
@@ -152,15 +166,15 @@ impl CodegenResult {
152
166
}
153
167
}
154
168
155
- impl ops:: Deref for CodegenResult {
169
+ impl < ' a > ops:: Deref for CodegenResult < ' a > {
156
170
type Target = Vec < P < ast:: Item > > ;
157
171
158
172
fn deref ( & self ) -> & Self :: Target {
159
173
& self . items
160
174
}
161
175
}
162
176
163
- impl ops:: DerefMut for CodegenResult {
177
+ impl < ' a > ops:: DerefMut for CodegenResult < ' a > {
164
178
fn deref_mut ( & mut self ) -> & mut Self :: Target {
165
179
& mut self . items
166
180
}
@@ -237,21 +251,21 @@ trait CodeGenerator {
237
251
/// Extra information from the caller.
238
252
type Extra ;
239
253
240
- fn codegen ( & self ,
241
- ctx : & BindgenContext ,
242
- result : & mut CodegenResult ,
243
- whitelisted_items : & ItemSet ,
244
- extra : & Self :: Extra ) ;
254
+ fn codegen < ' a > ( & self ,
255
+ ctx : & BindgenContext ,
256
+ result : & mut CodegenResult < ' a > ,
257
+ whitelisted_items : & ItemSet ,
258
+ extra : & Self :: Extra ) ;
245
259
}
246
260
247
261
impl CodeGenerator for Item {
248
262
type Extra = ( ) ;
249
263
250
- fn codegen ( & self ,
251
- ctx : & BindgenContext ,
252
- result : & mut CodegenResult ,
253
- whitelisted_items : & ItemSet ,
254
- _extra : & ( ) ) {
264
+ fn codegen < ' a > ( & self ,
265
+ ctx : & BindgenContext ,
266
+ result : & mut CodegenResult < ' a > ,
267
+ whitelisted_items : & ItemSet ,
268
+ _extra : & ( ) ) {
255
269
if self . is_hidden ( ctx) || result. seen ( self . id ( ) ) {
256
270
debug ! ( "<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
257
271
self = {:?}", self ) ;
@@ -288,11 +302,11 @@ impl CodeGenerator for Item {
288
302
impl CodeGenerator for Module {
289
303
type Extra = Item ;
290
304
291
- fn codegen ( & self ,
292
- ctx : & BindgenContext ,
293
- result : & mut CodegenResult ,
294
- whitelisted_items : & ItemSet ,
295
- item : & Item ) {
305
+ fn codegen < ' a > ( & self ,
306
+ ctx : & BindgenContext ,
307
+ result : & mut CodegenResult < ' a > ,
308
+ whitelisted_items : & ItemSet ,
309
+ item : & Item ) {
296
310
debug ! ( "<Module as CodeGenerator>::codegen: item = {:?}" , item) ;
297
311
298
312
let codegen_self = |result : & mut CodegenResult , found_any : & mut bool | {
@@ -348,11 +362,11 @@ impl CodeGenerator for Module {
348
362
349
363
impl CodeGenerator for Var {
350
364
type Extra = Item ;
351
- fn codegen ( & self ,
352
- ctx : & BindgenContext ,
353
- result : & mut CodegenResult ,
354
- _whitelisted_items : & ItemSet ,
355
- item : & Item ) {
365
+ fn codegen < ' a > ( & self ,
366
+ ctx : & BindgenContext ,
367
+ result : & mut CodegenResult < ' a > ,
368
+ _whitelisted_items : & ItemSet ,
369
+ item : & Item ) {
356
370
use ir:: var:: VarType ;
357
371
debug ! ( "<Var as CodeGenerator>::codegen: item = {:?}" , item) ;
358
372
@@ -439,11 +453,11 @@ impl CodeGenerator for Var {
439
453
impl CodeGenerator for Type {
440
454
type Extra = Item ;
441
455
442
- fn codegen ( & self ,
443
- ctx : & BindgenContext ,
444
- result : & mut CodegenResult ,
445
- whitelisted_items : & ItemSet ,
446
- item : & Item ) {
456
+ fn codegen < ' a > ( & self ,
457
+ ctx : & BindgenContext ,
458
+ result : & mut CodegenResult < ' a > ,
459
+ whitelisted_items : & ItemSet ,
460
+ item : & Item ) {
447
461
debug ! ( "<Type as CodeGenerator>::codegen: item = {:?}" , item) ;
448
462
449
463
match * self . kind ( ) {
@@ -560,11 +574,11 @@ impl<'a> Vtable<'a> {
560
574
impl < ' a > CodeGenerator for Vtable < ' a > {
561
575
type Extra = Item ;
562
576
563
- fn codegen ( & self ,
564
- ctx : & BindgenContext ,
565
- result : & mut CodegenResult ,
566
- _whitelisted_items : & ItemSet ,
567
- item : & Item ) {
577
+ fn codegen < ' b > ( & self ,
578
+ ctx : & BindgenContext ,
579
+ result : & mut CodegenResult < ' b > ,
580
+ _whitelisted_items : & ItemSet ,
581
+ item : & Item ) {
568
582
assert_eq ! ( item. id( ) , self . item_id) ;
569
583
// For now, generate an empty struct, later we should generate function
570
584
// pointers and whatnot.
@@ -694,11 +708,11 @@ impl<'a> Bitfield<'a> {
694
708
impl CodeGenerator for CompInfo {
695
709
type Extra = Item ;
696
710
697
- fn codegen ( & self ,
698
- ctx : & BindgenContext ,
699
- result : & mut CodegenResult ,
700
- whitelisted_items : & ItemSet ,
701
- item : & Item ) {
711
+ fn codegen < ' a > ( & self ,
712
+ ctx : & BindgenContext ,
713
+ result : & mut CodegenResult < ' a > ,
714
+ whitelisted_items : & ItemSet ,
715
+ item : & Item ) {
702
716
use aster:: struct_field:: StructFieldBuilder ;
703
717
704
718
debug ! ( "<CompInfo as CodeGenerator>::codegen: item = {:?}" , item) ;
@@ -713,7 +727,7 @@ impl CodeGenerator for CompInfo {
713
727
let layout = item. kind ( ) . expect_type ( ) . layout ( ctx) ;
714
728
715
729
if let Some ( layout) = layout {
716
- let fn_name = format ! ( "__bindgen_test_layout_template_{}" , item . id ( ) . as_usize ( ) ) ;
730
+ let fn_name = format ! ( "__bindgen_test_layout_template_{}" , result . next_id ( ) ) ;
717
731
let fn_name = ctx. rust_ident_raw ( & fn_name) ;
718
732
let ident = item. to_rust_ty ( ctx) ;
719
733
let prefix = ctx. trait_prefix ( ) ;
@@ -1222,23 +1236,23 @@ impl CodeGenerator for CompInfo {
1222
1236
}
1223
1237
1224
1238
trait MethodCodegen {
1225
- fn codegen_method ( & self ,
1226
- ctx : & BindgenContext ,
1227
- methods : & mut Vec < ast:: ImplItem > ,
1228
- method_names : & mut HashMap < String , usize > ,
1229
- result : & mut CodegenResult ,
1230
- whitelisted_items : & ItemSet ,
1231
- parent : & Item ) ;
1239
+ fn codegen_method < ' a > ( & self ,
1240
+ ctx : & BindgenContext ,
1241
+ methods : & mut Vec < ast:: ImplItem > ,
1242
+ method_names : & mut HashMap < String , usize > ,
1243
+ result : & mut CodegenResult < ' a > ,
1244
+ whitelisted_items : & ItemSet ,
1245
+ parent : & Item ) ;
1232
1246
}
1233
1247
1234
1248
impl MethodCodegen for Method {
1235
- fn codegen_method ( & self ,
1236
- ctx : & BindgenContext ,
1237
- methods : & mut Vec < ast:: ImplItem > ,
1238
- method_names : & mut HashMap < String , usize > ,
1239
- result : & mut CodegenResult ,
1240
- whitelisted_items : & ItemSet ,
1241
- _parent : & Item ) {
1249
+ fn codegen_method < ' a > ( & self ,
1250
+ ctx : & BindgenContext ,
1251
+ methods : & mut Vec < ast:: ImplItem > ,
1252
+ method_names : & mut HashMap < String , usize > ,
1253
+ result : & mut CodegenResult < ' a > ,
1254
+ whitelisted_items : & ItemSet ,
1255
+ _parent : & Item ) {
1242
1256
if self . is_virtual ( ) {
1243
1257
return ; // FIXME
1244
1258
}
@@ -1408,13 +1422,13 @@ impl<'a> EnumBuilder<'a> {
1408
1422
}
1409
1423
1410
1424
/// Add a variant to this enum.
1411
- fn with_variant ( self ,
1412
- ctx : & BindgenContext ,
1413
- variant : & EnumVariant ,
1414
- mangling_prefix : Option < & String > ,
1415
- rust_ty : P < ast:: Ty > ,
1416
- result : & mut CodegenResult )
1417
- -> Self {
1425
+ fn with_variant < ' b > ( self ,
1426
+ ctx : & BindgenContext ,
1427
+ variant : & EnumVariant ,
1428
+ mangling_prefix : Option < & String > ,
1429
+ rust_ty : P < ast:: Ty > ,
1430
+ result : & mut CodegenResult < ' b > )
1431
+ -> Self {
1418
1432
let variant_name = ctx. rust_mangle ( variant. name ( ) ) ;
1419
1433
let expr = aster:: AstBuilder :: new ( ) . expr ( ) ;
1420
1434
let expr = match variant. val ( ) {
@@ -1456,11 +1470,11 @@ impl<'a> EnumBuilder<'a> {
1456
1470
}
1457
1471
}
1458
1472
1459
- fn build ( self ,
1460
- ctx : & BindgenContext ,
1461
- rust_ty : P < ast:: Ty > ,
1462
- result : & mut CodegenResult )
1463
- -> P < ast:: Item > {
1473
+ fn build < ' b > ( self ,
1474
+ ctx : & BindgenContext ,
1475
+ rust_ty : P < ast:: Ty > ,
1476
+ result : & mut CodegenResult < ' b > )
1477
+ -> P < ast:: Item > {
1464
1478
match self {
1465
1479
EnumBuilder :: Rust ( b) => b. build ( ) ,
1466
1480
EnumBuilder :: Bitfield { canonical_name, aster } => {
@@ -1489,11 +1503,11 @@ impl<'a> EnumBuilder<'a> {
1489
1503
impl CodeGenerator for Enum {
1490
1504
type Extra = Item ;
1491
1505
1492
- fn codegen ( & self ,
1493
- ctx : & BindgenContext ,
1494
- result : & mut CodegenResult ,
1495
- _whitelisted_items : & ItemSet ,
1496
- item : & Item ) {
1506
+ fn codegen < ' a > ( & self ,
1507
+ ctx : & BindgenContext ,
1508
+ result : & mut CodegenResult < ' a > ,
1509
+ _whitelisted_items : & ItemSet ,
1510
+ item : & Item ) {
1497
1511
debug ! ( "<Enum as CodeGenerator>::codegen: item = {:?}" , item) ;
1498
1512
1499
1513
let name = item. canonical_name ( ctx) ;
@@ -1567,15 +1581,15 @@ impl CodeGenerator for Enum {
1567
1581
1568
1582
builder = builder. with_attr ( derives) ;
1569
1583
1570
- fn add_constant ( enum_ : & Type ,
1571
- // Only to avoid recomputing every time.
1572
- enum_canonical_name : & str ,
1573
- // May be the same as "variant" if it's because the
1574
- // enum is unnamed and we still haven't seen the value.
1575
- variant_name : & str ,
1576
- referenced_name : & str ,
1577
- enum_rust_ty : P < ast:: Ty > ,
1578
- result : & mut CodegenResult ) {
1584
+ fn add_constant < ' a > ( enum_ : & Type ,
1585
+ // Only to avoid recomputing every time.
1586
+ enum_canonical_name : & str ,
1587
+ // May be the same as "variant" if it's because the
1588
+ // enum is unnamed and we still haven't seen the value.
1589
+ variant_name : & str ,
1590
+ referenced_name : & str ,
1591
+ enum_rust_ty : P < ast:: Ty > ,
1592
+ result : & mut CodegenResult < ' a > ) {
1579
1593
let constant_name = if enum_. name ( ) . is_some ( ) {
1580
1594
format ! ( "{}_{}" , enum_canonical_name, variant_name)
1581
1595
} else {
@@ -1935,11 +1949,11 @@ impl ToRustTy for FunctionSig {
1935
1949
impl CodeGenerator for Function {
1936
1950
type Extra = Item ;
1937
1951
1938
- fn codegen ( & self ,
1939
- ctx : & BindgenContext ,
1940
- result : & mut CodegenResult ,
1941
- _whitelisted_items : & ItemSet ,
1942
- item : & Item ) {
1952
+ fn codegen < ' a > ( & self ,
1953
+ ctx : & BindgenContext ,
1954
+ result : & mut CodegenResult < ' a > ,
1955
+ _whitelisted_items : & ItemSet ,
1956
+ item : & Item ) {
1943
1957
debug ! ( "<Function as CodeGenerator>::codegen: item = {:?}" , item) ;
1944
1958
1945
1959
let name = self . name ( ) ;
@@ -2007,7 +2021,8 @@ impl CodeGenerator for Function {
2007
2021
2008
2022
pub fn codegen ( context : & mut BindgenContext ) -> Vec < P < ast:: Item > > {
2009
2023
context. gen ( |context| {
2010
- let mut result = CodegenResult :: new ( ) ;
2024
+ let counter = Cell :: new ( 0 ) ;
2025
+ let mut result = CodegenResult :: new ( & counter) ;
2011
2026
2012
2027
debug ! ( "codegen: {:?}" , context. options( ) ) ;
2013
2028
0 commit comments