@@ -13,7 +13,7 @@ mod bitfield_unit_tests;
13
13
use self :: helpers:: attributes;
14
14
use self :: struct_layout:: StructLayoutTracker ;
15
15
16
- use super :: BindgenOptions ;
16
+ use super :: { BindgenOptions , LayoutTests } ;
17
17
18
18
use ir:: analysis:: { HasVtable , Sizedness } ;
19
19
use ir:: annotations:: FieldAccessorKind ;
@@ -98,6 +98,12 @@ fn root_import(
98
98
struct CodegenResult < ' a > {
99
99
items : Vec < proc_macro2:: TokenStream > ,
100
100
101
+ /// Just the layout tests.
102
+ ///
103
+ /// Used to implement `LayoutTests::EmitOnly`, and empty if that setting is
104
+ /// disabled (note that conversely `items` is always populted).
105
+ only_tests : Vec < proc_macro2:: TokenStream > ,
106
+
101
107
/// A monotonic counter used to add stable unique id's to stuff that doesn't
102
108
/// need to be referenced by anything.
103
109
codegen_id : & ' a Cell < usize > ,
@@ -147,6 +153,7 @@ impl<'a> CodegenResult<'a> {
147
153
fn new ( codegen_id : & ' a Cell < usize > ) -> Self {
148
154
CodegenResult {
149
155
items : vec ! [ ] ,
156
+ only_tests : vec ! [ ] ,
150
157
saw_bindgen_union : false ,
151
158
saw_incomplete_array : false ,
152
159
saw_objc : false ,
@@ -214,7 +221,10 @@ impl<'a> CodegenResult<'a> {
214
221
self . vars_seen . insert ( name. into ( ) ) ;
215
222
}
216
223
217
- fn inner < F > ( & mut self , cb : F ) -> Vec < proc_macro2:: TokenStream >
224
+ fn inner < F > (
225
+ & mut self ,
226
+ cb : F ,
227
+ ) -> ( Vec < proc_macro2:: TokenStream > , Vec < proc_macro2:: TokenStream > )
218
228
where
219
229
F : FnOnce ( & mut Self ) ,
220
230
{
@@ -228,7 +238,7 @@ impl<'a> CodegenResult<'a> {
228
238
self . saw_bitfield_unit |= new. saw_bitfield_unit ;
229
239
self . saw_bindgen_union |= new. saw_bindgen_union ;
230
240
231
- new. items
241
+ ( new. items , new . only_tests )
232
242
}
233
243
}
234
244
@@ -435,7 +445,7 @@ impl CodeGenerator for Module {
435
445
}
436
446
437
447
let mut found_any = false ;
438
- let inner_items = result. inner ( |result| {
448
+ let ( inner_items, inner_tests ) = result. inner ( |result| {
439
449
result. push ( root_import ( ctx, item) ) ;
440
450
441
451
let path = item. namespace_aware_canonical_path ( ctx) . join ( "::" ) ;
@@ -457,7 +467,7 @@ impl CodeGenerator for Module {
457
467
}
458
468
459
469
let name = item. canonical_name ( ctx) ;
460
- let ident = ctx. rust_ident ( name) ;
470
+ let ident = ctx. rust_ident ( & name) ;
461
471
result. push ( if item. id ( ) == ctx. root_module ( ) {
462
472
quote ! {
463
473
#[ allow( non_snake_case, non_camel_case_types, non_upper_case_globals) ]
@@ -472,6 +482,19 @@ impl CodeGenerator for Module {
472
482
}
473
483
}
474
484
} ) ;
485
+ if ctx. options ( ) . layout_tests == LayoutTests :: EmitOnly &&
486
+ !result. only_tests . is_empty ( )
487
+ {
488
+ // XXX the following appears to work? Or should this just be unsupported.
489
+ let test_mod =
490
+ ctx. rust_ident ( format ! ( "__bindgen_test_mod_{}" , name) ) ;
491
+ result. only_tests . push ( quote ! {
492
+ mod #test_mod {
493
+ use super :: #ident:: * ;
494
+ #( #inner_tests ) *
495
+ }
496
+ } ) ;
497
+ }
475
498
}
476
499
}
477
500
@@ -959,7 +982,7 @@ impl CodeGenerator for TemplateInstantiation {
959
982
// instantiation is opaque, then its presumably because we don't
960
983
// properly understand it (maybe because of specializations), and so we
961
984
// shouldn't emit layout tests either.
962
- if !ctx. options ( ) . layout_tests || self . is_opaque ( ctx, item) {
985
+ if !ctx. options ( ) . layout_tests . needed ( ) || self . is_opaque ( ctx, item) {
963
986
return ;
964
987
}
965
988
@@ -1006,7 +1029,9 @@ impl CodeGenerator for TemplateInstantiation {
1006
1029
stringify!( #ident) ) ) ;
1007
1030
}
1008
1031
} ;
1009
-
1032
+ if ctx. options ( ) . layout_tests == LayoutTests :: EmitOnly {
1033
+ result. only_tests . push ( item. clone ( ) ) ;
1034
+ }
1010
1035
result. push ( item) ;
1011
1036
}
1012
1037
}
@@ -1899,7 +1924,9 @@ impl CodeGenerator for CompInfo {
1899
1924
}
1900
1925
}
1901
1926
1902
- if ctx. options ( ) . layout_tests && !self . is_forward_declaration ( ) {
1927
+ if ctx. options ( ) . layout_tests . needed ( ) &&
1928
+ !self . is_forward_declaration ( )
1929
+ {
1903
1930
if let Some ( layout) = layout {
1904
1931
let fn_name =
1905
1932
format ! ( "bindgen_test_layout_{}" , canonical_ident) ;
@@ -1982,6 +2009,9 @@ impl CodeGenerator for CompInfo {
1982
2009
#( #check_field_offset ) *
1983
2010
}
1984
2011
} ;
2012
+ if ctx. options ( ) . layout_tests == LayoutTests :: EmitOnly {
2013
+ result. only_tests . push ( item. clone ( ) ) ;
2014
+ }
1985
2015
result. push ( item) ;
1986
2016
}
1987
2017
}
@@ -3848,8 +3878,11 @@ pub(crate) fn codegen(
3848
3878
& mut result,
3849
3879
& ( ) ,
3850
3880
) ;
3851
-
3852
- result. items
3881
+ if LayoutTests :: EmitOnly == context. options ( ) . layout_tests {
3882
+ result. only_tests
3883
+ } else {
3884
+ result. items
3885
+ }
3853
3886
} )
3854
3887
}
3855
3888
0 commit comments