@@ -427,6 +427,54 @@ fn test_header_contents() {
427427 assert_eq ! ( expected, actual) ;
428428}
429429
430+ const HIDDEN_FUNCTIONS_HEADER : & str = r#"
431+ __attribute__((visibility("hidden"))) int hidden_fn(void);
432+ __attribute__((visibility("protected"))) int protected_fn(void);
433+ int visible_fn(void);
434+ "# ;
435+
436+ fn hidden_functions_builder ( ) -> Builder {
437+ builder ( )
438+ . allowlist_function ( "visible_fn" )
439+ . allowlist_function ( "hidden_fn" )
440+ . allowlist_function ( "protected_fn" )
441+ . header_contents ( "hidden.h" , HIDDEN_FUNCTIONS_HEADER )
442+ }
443+
444+ #[ test]
445+ fn hidden_functions_are_skipped_by_default ( ) {
446+ let bindings = hidden_functions_builder ( )
447+ . generate ( )
448+ . unwrap ( )
449+ . to_string ( ) ;
450+
451+ assert ! ( bindings. contains( "pub fn visible_fn" ) ) ;
452+ assert ! ( !bindings. contains( "pub fn hidden_fn" ) ) ;
453+ }
454+
455+ #[ test]
456+ fn hidden_functions_can_be_generated_when_enabled ( ) {
457+ let default_bindings = hidden_functions_builder ( )
458+ . generate ( )
459+ . unwrap ( )
460+ . to_string ( ) ;
461+
462+ let hidden_enabled = hidden_functions_builder ( )
463+ . generate_hidden_functions ( true )
464+ . generate ( )
465+ . unwrap ( )
466+ . to_string ( ) ;
467+
468+ assert ! ( hidden_enabled. contains( "pub fn hidden_fn" ) ) ;
469+ assert ! ( !default_bindings. contains( "pub fn hidden_fn" ) ) ;
470+
471+ // Clang on Mach-O downgrades `protected` visibility to `default`,
472+ // so the symbol might already be present without the new option.
473+ if !default_bindings. contains ( "pub fn protected_fn" ) {
474+ assert ! ( hidden_enabled. contains( "pub fn protected_fn" ) ) ;
475+ }
476+ }
477+
430478#[ test]
431479fn test_multiple_header_calls_in_builder ( ) {
432480 let actual = builder ( )
0 commit comments