@@ -9,6 +9,7 @@ use ir::item_kind::ItemKind;
9
9
use ir:: comp:: { CompKind , CompInfo , Method } ;
10
10
use ir:: layout:: Layout ;
11
11
12
+ use std:: ops;
12
13
use std:: collections:: hash_map:: { HashMap , Entry } ;
13
14
14
15
use syntax:: abi:: Abi ;
@@ -44,6 +45,38 @@ macro_rules! link_name {
44
45
} }
45
46
}
46
47
48
+ struct CodegenResult {
49
+ items : Vec < P < ast:: Item > > ,
50
+ saw_union : bool ,
51
+ }
52
+
53
+ impl CodegenResult {
54
+ fn new ( ) -> Self {
55
+ CodegenResult {
56
+ items : vec ! [ ] ,
57
+ saw_union : false ,
58
+ }
59
+ }
60
+
61
+ fn saw_union ( & mut self ) {
62
+ self . saw_union = true ;
63
+ }
64
+ }
65
+
66
+ impl ops:: Deref for CodegenResult {
67
+ type Target = Vec < P < ast:: Item > > ;
68
+
69
+ fn deref ( & self ) -> & Self :: Target {
70
+ & self . items
71
+ }
72
+ }
73
+
74
+ impl ops:: DerefMut for CodegenResult {
75
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
76
+ & mut self . items
77
+ }
78
+ }
79
+
47
80
struct ForeignModBuilder {
48
81
inner : ast:: ForeignMod ,
49
82
}
@@ -242,7 +275,7 @@ trait CodeGenerator {
242
275
243
276
fn codegen ( & self ,
244
277
ctx : & BindgenContext ,
245
- result : & mut Vec < P < ast :: Item > > ,
278
+ result : & mut CodegenResult ,
246
279
extra : & Self :: Extra ) ;
247
280
}
248
281
@@ -251,7 +284,7 @@ impl CodeGenerator for Item {
251
284
252
285
fn codegen ( & self ,
253
286
ctx : & BindgenContext ,
254
- result : & mut Vec < P < ast :: Item > > ,
287
+ result : & mut CodegenResult ,
255
288
_extra : & ( ) ) {
256
289
match * self . kind ( ) {
257
290
ItemKind :: Module ( ..) => { /* TODO */ } ,
@@ -272,7 +305,7 @@ impl CodeGenerator for Var {
272
305
type Extra = Item ;
273
306
fn codegen ( & self ,
274
307
ctx : & BindgenContext ,
275
- result : & mut Vec < P < ast :: Item > > ,
308
+ result : & mut CodegenResult ,
276
309
item : & Item ) {
277
310
let name = item. canonical_name ( ctx) ;
278
311
let ty = self . ty ( ) . to_rust_ty ( ctx) ;
@@ -312,7 +345,7 @@ impl CodeGenerator for Type {
312
345
313
346
fn codegen ( & self ,
314
347
ctx : & BindgenContext ,
315
- result : & mut Vec < P < ast :: Item > > ,
348
+ result : & mut CodegenResult ,
316
349
item : & Item ) {
317
350
match * self . kind ( ) {
318
351
TypeKind :: Void |
@@ -382,7 +415,7 @@ impl<'a> CodeGenerator for Vtable<'a> {
382
415
383
416
fn codegen ( & self ,
384
417
ctx : & BindgenContext ,
385
- result : & mut Vec < P < ast :: Item > > ,
418
+ result : & mut CodegenResult ,
386
419
item : & Item ) {
387
420
assert_eq ! ( item. id( ) , self . item_id) ;
388
421
// For now, generate an empty struct, later we should generate function
@@ -406,7 +439,7 @@ impl CodeGenerator for CompInfo {
406
439
407
440
fn codegen ( & self ,
408
441
ctx : & BindgenContext ,
409
- result : & mut Vec < P < ast :: Item > > ,
442
+ result : & mut CodegenResult ,
410
443
item : & Item ) {
411
444
use aster:: struct_field:: StructFieldBuilder ;
412
445
// Don't output classes with template parameters that aren't types, and
@@ -460,6 +493,11 @@ impl CodeGenerator for CompInfo {
460
493
fields. push ( field) ;
461
494
}
462
495
496
+ let is_union = self . kind ( ) == CompKind :: Union ;
497
+ if is_union {
498
+ result. saw_union ( ) ;
499
+ }
500
+
463
501
for field in self . fields ( ) {
464
502
if let Some ( _width) = field. bitfield ( ) {
465
503
// TODO: Compute bitfields.
@@ -473,15 +511,33 @@ impl CodeGenerator for CompInfo {
473
511
}
474
512
}
475
513
476
- let ty = field. ty ( ) . to_rust_ty ( ctx) ;
477
- let mut attrs = vec ! [ ] ;
478
- if let Some ( comment) = field. comment ( ) {
479
- attrs. push ( doc ! ( comment) ) ;
514
+ if !is_union {
515
+ let ty = field. ty ( ) . to_rust_ty ( ctx) ;
516
+
517
+ let ty = if is_union {
518
+ quote_ty ! ( ctx. ext_cx( ) , __BindgenUnionField<$ty>)
519
+ } else {
520
+ ty
521
+ } ;
522
+
523
+ let mut attrs = vec ! [ ] ;
524
+ if let Some ( comment) = field. comment ( ) {
525
+ attrs. push ( doc ! ( comment) ) ;
526
+ }
527
+
528
+ let field = StructFieldBuilder :: named ( field. name ( ) ) . pub_ ( )
529
+ . with_attrs ( attrs)
530
+ . build_ty ( ty) ;
531
+ fields. push ( field) ;
480
532
}
533
+ }
481
534
482
- let field = StructFieldBuilder :: named ( field. name ( ) ) . pub_ ( )
483
- . with_attrs ( attrs)
484
- . build_ty ( ty) ;
535
+ if is_union {
536
+ let layout = item. kind ( ) . expect_type ( ) . layout ( ctx)
537
+ . expect ( "Unable to get layout information?" ) ;
538
+ let ty = BlobTyBuilder :: new ( layout) . build ( ) ;
539
+ let field = StructFieldBuilder :: named ( "bindgen_union_field" ) . pub_ ( )
540
+ . build_ty ( ty) ;
485
541
fields. push ( field) ;
486
542
}
487
543
@@ -536,7 +592,7 @@ impl CodeGenerator for Enum {
536
592
537
593
fn codegen ( & self ,
538
594
ctx : & BindgenContext ,
539
- result : & mut Vec < P < ast :: Item > > ,
595
+ result : & mut CodegenResult ,
540
596
item : & Item ) {
541
597
use ir:: enum_ty:: EnumVariantValue ;
542
598
@@ -831,7 +887,7 @@ impl CodeGenerator for Function {
831
887
832
888
fn codegen ( & self ,
833
889
ctx : & BindgenContext ,
834
- result : & mut Vec < P < ast :: Item > > ,
890
+ result : & mut CodegenResult ,
835
891
item : & Item ) {
836
892
let signature_item = ctx. resolve_item ( self . signature ( ) ) ;
837
893
let signature = signature_item. kind ( ) . expect_type ( ) ;
0 commit comments