@@ -592,6 +592,10 @@ impl Builder {
592
592
output_vector. push ( "--sort-semantically" . into ( ) ) ;
593
593
}
594
594
595
+ if self . options . unsafe_blocks {
596
+ output_vector. push ( "--unsafe-blocks" . into ( ) ) ;
597
+ }
598
+
595
599
// Add clang arguments
596
600
597
601
output_vector. push ( "--" . into ( ) ) ;
@@ -1489,6 +1493,12 @@ impl Builder {
1489
1493
self
1490
1494
}
1491
1495
1496
+ /// If true, wraps all the bodies of generated `unsafe` functions in `unsafe` blocks.
1497
+ pub fn unsafe_blocks ( mut self , doit : bool ) -> Self {
1498
+ self . options . unsafe_blocks = doit;
1499
+ self
1500
+ }
1501
+
1492
1502
/// Generate the Rust bindings using the options built up thus far.
1493
1503
pub fn generate ( mut self ) -> Result < Bindings , BindgenError > {
1494
1504
// Add any extra arguments from the environment to the clang command line.
@@ -2021,6 +2031,9 @@ struct BindgenOptions {
2021
2031
2022
2032
/// Sort the code generation
2023
2033
sort_semantically : bool ,
2034
+
2035
+ /// Wrap the bodies of `unsafe` functions in `unsafe` blocks
2036
+ unsafe_blocks : bool ,
2024
2037
}
2025
2038
2026
2039
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -2031,7 +2044,7 @@ impl ::std::panic::UnwindSafe for BindgenOptions {}
2031
2044
impl BindgenOptions {
2032
2045
/// Whether any of the enabled options requires `syn`.
2033
2046
fn require_syn ( & self ) -> bool {
2034
- self . sort_semantically
2047
+ self . sort_semantically || self . unsafe_blocks
2035
2048
}
2036
2049
2037
2050
fn build ( & mut self ) {
@@ -2175,6 +2188,7 @@ impl Default for BindgenOptions {
2175
2188
force_explicit_padding : false ,
2176
2189
vtable_generation : false ,
2177
2190
sort_semantically : false ,
2191
+ unsafe_blocks : Default :: default ( ) ,
2178
2192
}
2179
2193
}
2180
2194
}
@@ -2503,6 +2517,71 @@ impl Bindings {
2503
2517
} ) ;
2504
2518
}
2505
2519
2520
+ if options. unsafe_blocks {
2521
+ struct UnsafeBlocksVisitor ;
2522
+
2523
+ impl UnsafeBlocksVisitor {
2524
+ fn add_unsafe_block (
2525
+ & self ,
2526
+ sig : & syn:: Signature ,
2527
+ block : & mut syn:: Block ,
2528
+ ) {
2529
+ if sig. unsafety . is_some ( ) {
2530
+ let inner_block = std:: mem:: replace (
2531
+ block,
2532
+ syn:: Block {
2533
+ brace_token : Default :: default ( ) ,
2534
+ stmts : Default :: default ( ) ,
2535
+ } ,
2536
+ ) ;
2537
+
2538
+ block. stmts . push ( syn:: Stmt :: Expr (
2539
+ syn:: Expr :: Unsafe ( syn:: ExprUnsafe {
2540
+ attrs : Default :: default ( ) ,
2541
+ block : inner_block,
2542
+ unsafe_token : Default :: default ( ) ,
2543
+ } ) ,
2544
+ ) ) ;
2545
+ }
2546
+ }
2547
+ }
2548
+
2549
+ impl syn:: visit_mut:: VisitMut for UnsafeBlocksVisitor {
2550
+ fn visit_item_fn_mut ( & mut self , item : & mut syn:: ItemFn ) {
2551
+ self . add_unsafe_block ( & item. sig , & mut item. block ) ;
2552
+
2553
+ syn:: visit_mut:: visit_item_fn_mut ( self , item)
2554
+ }
2555
+
2556
+ fn visit_impl_item_method_mut (
2557
+ & mut self ,
2558
+ item : & mut syn:: ImplItemMethod ,
2559
+ ) {
2560
+ self . add_unsafe_block ( & item. sig , & mut item. block ) ;
2561
+
2562
+ syn:: visit_mut:: visit_impl_item_method_mut ( self , item)
2563
+ }
2564
+
2565
+ fn visit_trait_item_method_mut (
2566
+ & mut self ,
2567
+ item : & mut syn:: TraitItemMethod ,
2568
+ ) {
2569
+ if let Some ( ref mut block) = item. default {
2570
+ self . add_unsafe_block ( & item. sig , block) ;
2571
+ }
2572
+
2573
+ syn:: visit_mut:: visit_trait_item_method_mut ( self , item)
2574
+ }
2575
+ }
2576
+
2577
+ for item in & mut syn_parsed_items {
2578
+ syn:: visit_mut:: visit_item_mut (
2579
+ & mut UnsafeBlocksVisitor ,
2580
+ item,
2581
+ ) ;
2582
+ }
2583
+ }
2584
+
2506
2585
let synful_items = syn_parsed_items
2507
2586
. into_iter ( )
2508
2587
. map ( |item| item. into_token_stream ( ) ) ;
0 commit comments