@@ -157,11 +157,16 @@ pub struct BindgenContext<'ctx> {
157
157
/// Whether a bindgen complex was generated
158
158
generated_bindegen_complex : Cell < bool > ,
159
159
160
- /// The set of `ItemId`s that are whitelisted for code generation. This the
161
- /// very first thing computed after parsing our IR, and before running any
162
- /// of our analyses.
160
+ /// The set of `ItemId`s that are whitelisted. This the very first thing
161
+ /// computed after parsing our IR, and before running any of our analyses.
163
162
whitelisted : Option < ItemSet > ,
164
163
164
+ /// The set of `ItemId`s that are whitelisted for code generation _and_ that
165
+ /// we should generate accounting for the codegen options.
166
+ ///
167
+ /// It's computed right after computing the whitelisted items.
168
+ codegen_items : Option < ItemSet > ,
169
+
165
170
/// Map from an item's id to the set of template parameter items that it
166
171
/// uses. See `ir::named` for more details. Always `Some` during the codegen
167
172
/// phase.
@@ -182,7 +187,7 @@ pub struct BindgenContext<'ctx> {
182
187
}
183
188
184
189
/// A traversal of whitelisted items.
185
- pub struct WhitelistedItems < ' ctx , ' gen >
190
+ struct WhitelistedItemsTraversal < ' ctx , ' gen >
186
191
where ' gen : ' ctx
187
192
{
188
193
ctx : & ' ctx BindgenContext < ' gen > ,
@@ -193,7 +198,7 @@ pub struct WhitelistedItems<'ctx, 'gen>
193
198
for <' a > fn ( & ' a BindgenContext , Edge ) -> bool > ,
194
199
}
195
200
196
- impl < ' ctx , ' gen > Iterator for WhitelistedItems < ' ctx , ' gen >
201
+ impl < ' ctx , ' gen > Iterator for WhitelistedItemsTraversal < ' ctx , ' gen >
197
202
where ' gen : ' ctx
198
203
{
199
204
type Item = ItemId ;
@@ -209,26 +214,23 @@ impl<'ctx, 'gen> Iterator for WhitelistedItems<'ctx, 'gen>
209
214
}
210
215
}
211
216
212
- impl < ' ctx , ' gen > WhitelistedItems < ' ctx , ' gen >
217
+ impl < ' ctx , ' gen > WhitelistedItemsTraversal < ' ctx , ' gen >
213
218
where ' gen : ' ctx
214
219
{
215
220
/// Construct a new whitelisted items traversal.
216
221
pub fn new < R > ( ctx : & ' ctx BindgenContext < ' gen > ,
217
- roots : R )
218
- -> WhitelistedItems < ' ctx , ' gen >
222
+ roots : R ,
223
+ predicate : for <' a > fn ( & ' a BindgenContext , Edge ) -> bool )
224
+ -> Self
219
225
where R : IntoIterator < Item = ItemId > ,
220
226
{
221
- let predicate = if ctx. options ( ) . whitelist_recursively {
222
- traversal:: all_edges
223
- } else {
224
- traversal:: no_edges
225
- } ;
226
- WhitelistedItems {
227
+ WhitelistedItemsTraversal {
227
228
ctx : ctx,
228
229
traversal : ItemTraversal :: new ( ctx, roots, predicate)
229
230
}
230
231
}
231
232
}
233
+
232
234
impl < ' ctx > BindgenContext < ' ctx > {
233
235
/// Construct the context for the given `options`.
234
236
pub fn new ( options : BindgenOptions ) -> Self {
@@ -303,6 +305,7 @@ impl<'ctx> BindgenContext<'ctx> {
303
305
options : options,
304
306
generated_bindegen_complex : Cell :: new ( false ) ,
305
307
whitelisted : None ,
308
+ codegen_items : None ,
306
309
used_template_parameters : None ,
307
310
need_bitfield_allocation : Default :: default ( ) ,
308
311
needs_mangling_hack : needs_mangling_hack,
@@ -770,7 +773,7 @@ impl<'ctx> BindgenContext<'ctx> {
770
773
// Compute the whitelisted set after processing replacements and
771
774
// resolving type refs, as those are the final mutations of the IR
772
775
// graph, and their completion means that the IR graph is now frozen.
773
- self . compute_whitelisted_items ( ) ;
776
+ self . compute_whitelisted_and_codegen_items ( ) ;
774
777
775
778
// Make sure to do this after processing replacements, since that messes
776
779
// with the parentage and module children, and we want to assert that it
@@ -1589,15 +1592,22 @@ impl<'ctx> BindgenContext<'ctx> {
1589
1592
self . whitelisted . as_ref ( ) . unwrap ( )
1590
1593
}
1591
1594
1595
+ /// Get a reference to the set of items we should generate.
1596
+ pub fn codegen_items ( & self ) -> & ItemSet {
1597
+ assert ! ( self . in_codegen_phase( ) ) ;
1598
+ assert ! ( self . current_module == self . root_module) ;
1599
+ self . codegen_items . as_ref ( ) . unwrap ( )
1600
+ }
1601
+
1592
1602
/// Compute the whitelisted items set and populate `self.whitelisted`.
1593
- fn compute_whitelisted_items ( & mut self ) {
1603
+ fn compute_whitelisted_and_codegen_items ( & mut self ) {
1594
1604
assert ! ( self . in_codegen_phase( ) ) ;
1595
1605
assert ! ( self . current_module == self . root_module) ;
1596
1606
assert ! ( self . whitelisted. is_none( ) ) ;
1597
1607
1598
- self . whitelisted = Some ( {
1599
- let roots = self . items ( )
1600
- // Only consider items that are enabled for codegen.
1608
+ let roots = {
1609
+ let mut roots = self . items ( )
1610
+ // Only consider roots that are enabled for codegen.
1601
1611
. filter ( |& ( _, item) | item. is_enabled_for_codegen ( self ) )
1602
1612
. filter ( |& ( _, item) | {
1603
1613
// If nothing is explicitly whitelisted, then everything is fair
@@ -1657,16 +1667,43 @@ impl<'ctx> BindgenContext<'ctx> {
1657
1667
}
1658
1668
}
1659
1669
} )
1660
- . map ( |( & id, _) | id) ;
1670
+ . map ( |( & id, _) | id)
1671
+ . collect :: < Vec < _ > > ( ) ;
1661
1672
1662
- // The reversal preserves the expected ordering of traversal, resulting
1663
- // in more stable-ish bindgen-generated names for anonymous types (like
1664
- // unions).
1665
- let mut roots: Vec < _ > = roots. collect ( ) ;
1673
+ // The reversal preserves the expected ordering of traversal,
1674
+ // resulting in more stable-ish bindgen-generated names for
1675
+ // anonymous types (like unions).
1666
1676
roots. reverse ( ) ;
1677
+ roots
1678
+ } ;
1667
1679
1668
- WhitelistedItems :: new ( self , roots) . collect ( )
1669
- } ) ;
1680
+ let whitelisted_items_predicate =
1681
+ if self . options ( ) . whitelist_recursively {
1682
+ traversal:: all_edges
1683
+ } else {
1684
+ traversal:: no_edges
1685
+ } ;
1686
+
1687
+ let whitelisted =
1688
+ WhitelistedItemsTraversal :: new (
1689
+ self ,
1690
+ roots. clone ( ) ,
1691
+ whitelisted_items_predicate,
1692
+ ) . collect :: < ItemSet > ( ) ;
1693
+
1694
+ let codegen_items =
1695
+ if self . options ( ) . whitelist_recursively {
1696
+ WhitelistedItemsTraversal :: new (
1697
+ self ,
1698
+ roots. clone ( ) ,
1699
+ traversal:: codegen_edges,
1700
+ ) . collect :: < ItemSet > ( )
1701
+ } else {
1702
+ whitelisted. clone ( )
1703
+ } ;
1704
+
1705
+ self . whitelisted = Some ( whitelisted) ;
1706
+ self . codegen_items = Some ( codegen_items) ;
1670
1707
}
1671
1708
1672
1709
/// Convenient method for getting the prefix to use for most traits in
0 commit comments