Skip to content

Commit 1e00d63

Browse files
committed
Add "--no-default [regex]" flag
Add a command line flag "--no-default [regex]" which ensures that any types matching "[regex]" will neither derive nor Impl Default. Add the corresponding builder command "no_default(regex)" which has the same behavior for invocations of bindgen via Builder.
1 parent 1111301 commit 1e00d63

14 files changed

+252
-1
lines changed

src/ir/analysis/derive.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ impl DeriveTrait {
454454
fn not_by_name(&self, ctx: &BindgenContext, item: &Item) -> bool {
455455
match self {
456456
DeriveTrait::Copy => ctx.no_copy_by_name(item),
457+
DeriveTrait::Default => ctx.no_default_by_name(item),
457458
DeriveTrait::Hash => ctx.no_hash_by_name(item),
458459
DeriveTrait::PartialEqOrPartialOrd => {
459460
ctx.no_partialeq_by_name(item)

src/ir/context.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,6 +2644,12 @@ If you encounter an error missing from this list, please file an issue or a PR!"
26442644
let name = item.path_for_whitelisting(self)[1..].join("::");
26452645
self.options().no_hash_types.matches(&name)
26462646
}
2647+
2648+
/// Check if `--no-default` flag is enabled for this item.
2649+
pub fn no_default_by_name(&self, item: &Item) -> bool {
2650+
let name = item.path_for_whitelisting(self)[1..].join("::");
2651+
self.options().no_default_types.matches(&name)
2652+
}
26472653
}
26482654

26492655
/// A builder struct for configuring item resolution options.

src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,16 @@ impl Builder {
648648
})
649649
.count();
650650

651+
self.options
652+
.no_default_types
653+
.get_items()
654+
.iter()
655+
.map(|item| {
656+
output_vector.push("--no-default".into());
657+
output_vector.push(item.to_owned());
658+
})
659+
.count();
660+
651661
output_vector
652662
}
653663

@@ -1507,6 +1517,13 @@ impl Builder {
15071517
self.options.wasm_import_module_name = Some(import_name.into());
15081518
self
15091519
}
1520+
1521+
/// Don't derive `Default` for a given type. Regular
1522+
/// expressions are supported.
1523+
pub fn no_default<T: Into<String>>(mut self, arg: T) -> Builder {
1524+
self.options.no_default_types.insert(arg.into());
1525+
self
1526+
}
15101527
}
15111528

15121529
/// Configuration options for generated bindings.
@@ -1769,6 +1786,9 @@ struct BindgenOptions {
17691786

17701787
/// Wasm import module name.
17711788
wasm_import_module_name: Option<String>,
1789+
1790+
/// The set of types that we should not derive `Default` for.
1791+
no_default_types: RegexSet,
17721792
}
17731793

17741794
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1798,6 +1818,7 @@ impl BindgenOptions {
17981818
&mut self.no_partialeq_types,
17991819
&mut self.no_copy_types,
18001820
&mut self.no_hash_types,
1821+
&mut self.no_default_types,
18011822
];
18021823
let record_matches = self.record_matches;
18031824
for regex_set in &mut regex_sets {
@@ -1895,6 +1916,7 @@ impl Default for BindgenOptions {
18951916
no_hash_types: Default::default(),
18961917
array_pointers_in_arguments: false,
18971918
wasm_import_module_name: None,
1919+
no_default_types: Default::default(),
18981920
}
18991921
}
19001922
}

src/options.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,14 @@ where
438438
.long("wasm-import-module-name")
439439
.value_name("name")
440440
.takes_value(true)
441-
.help("The name to be used in a #[link(wasm_import_module = ...)] statement")
441+
.help("The name to be used in a #[link(wasm_import_module = ...)] statement"),
442+
Arg::with_name("no-default")
443+
.long("no-default")
444+
.help("Avoids deriving Default for types matching <regex>.")
445+
.value_name("regex")
446+
.takes_value(true)
447+
.multiple(true)
448+
.number_of_values(1),
442449
]) // .args()
443450
.get_matches_from(args);
444451

@@ -813,6 +820,12 @@ where
813820
}
814821
}
815822

823+
if let Some(no_default) = matches.values_of("no-default") {
824+
for regex in no_default {
825+
builder = builder.no_default(regex);
826+
}
827+
}
828+
816829
let verbose = matches.is_present("verbose");
817830

818831
Ok((builder, output, verbose))
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
#[repr(C)]
11+
#[derive(Debug, Copy, Clone)]
12+
pub struct NoDefault {
13+
_unused: [u8; 0],
14+
}
15+
pub type NoDefaultT = NoDefault;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
#[repr(C)]
11+
#[repr(align(4))]
12+
#[derive(Debug, Copy, Clone)]
13+
pub struct NoDefault {
14+
pub _bindgen_opaque_blob: u32,
15+
}
16+
#[test]
17+
fn bindgen_test_layout_NoDefault() {
18+
assert_eq!(
19+
::std::mem::size_of::<NoDefault>(),
20+
4usize,
21+
concat!("Size of: ", stringify!(NoDefault))
22+
);
23+
assert_eq!(
24+
::std::mem::align_of::<NoDefault>(),
25+
4usize,
26+
concat!("Alignment of ", stringify!(NoDefault))
27+
);
28+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
#[repr(C)]
11+
#[derive(Debug, Copy, Clone)]
12+
pub struct NoDefault {
13+
pub x: ::std::os::raw::c_int,
14+
}
15+
#[test]
16+
fn bindgen_test_layout_NoDefault() {
17+
assert_eq!(
18+
::std::mem::size_of::<NoDefault>(),
19+
4usize,
20+
concat!("Size of: ", stringify!(NoDefault))
21+
);
22+
assert_eq!(
23+
::std::mem::align_of::<NoDefault>(),
24+
4usize,
25+
concat!("Alignment of ", stringify!(NoDefault))
26+
);
27+
assert_eq!(
28+
unsafe { &(*(::std::ptr::null::<NoDefault>())).x as *const _ as usize },
29+
0usize,
30+
concat!(
31+
"Offset of field: ",
32+
stringify!(NoDefault),
33+
"::",
34+
stringify!(x)
35+
)
36+
);
37+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
#[repr(C)]
11+
#[derive(Debug, Copy, Clone)]
12+
pub struct NotDefault {
13+
pub x: ::std::os::raw::c_int,
14+
}
15+
#[test]
16+
fn bindgen_test_layout_NotDefault() {
17+
assert_eq!(
18+
::std::mem::size_of::<NotDefault>(),
19+
4usize,
20+
concat!("Size of: ", stringify!(NotDefault))
21+
);
22+
assert_eq!(
23+
::std::mem::align_of::<NotDefault>(),
24+
4usize,
25+
concat!("Alignment of ", stringify!(NotDefault))
26+
);
27+
assert_eq!(
28+
unsafe {
29+
&(*(::std::ptr::null::<NotDefault>())).x as *const _ as usize
30+
},
31+
0usize,
32+
concat!(
33+
"Offset of field: ",
34+
stringify!(NotDefault),
35+
"::",
36+
stringify!(x)
37+
)
38+
);
39+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
#[repr(C)]
11+
#[derive(Debug, Copy, Clone)]
12+
pub struct NoDefault {
13+
pub _address: u8,
14+
}
15+
#[test]
16+
fn bindgen_test_layout_NoDefault() {
17+
assert_eq!(
18+
::std::mem::size_of::<NoDefault>(),
19+
1usize,
20+
concat!("Size of: ", stringify!(NoDefault))
21+
);
22+
assert_eq!(
23+
::std::mem::align_of::<NoDefault>(),
24+
1usize,
25+
concat!("Alignment of ", stringify!(NoDefault))
26+
);
27+
}
28+
#[repr(C)]
29+
#[derive(Debug, Copy, Clone)]
30+
pub struct Whitelisted {
31+
pub x: NoDefault,
32+
}
33+
#[test]
34+
fn bindgen_test_layout_Whitelisted() {
35+
assert_eq!(
36+
::std::mem::size_of::<Whitelisted>(),
37+
1usize,
38+
concat!("Size of: ", stringify!(Whitelisted))
39+
);
40+
assert_eq!(
41+
::std::mem::align_of::<Whitelisted>(),
42+
1usize,
43+
concat!("Alignment of ", stringify!(Whitelisted))
44+
);
45+
assert_eq!(
46+
unsafe {
47+
&(*(::std::ptr::null::<Whitelisted>())).x as *const _ as usize
48+
},
49+
0usize,
50+
concat!(
51+
"Offset of field: ",
52+
stringify!(Whitelisted),
53+
"::",
54+
stringify!(x)
55+
)
56+
);
57+
}

tests/headers/forward-no-default.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// bindgen-flags: --no-default NoDefault
2+
3+
typedef struct NoDefault NoDefaultT;

tests/headers/no-default-opaque.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// bindgen-flags: --no-default "NoDefault" --opaque-type "NoDefault"
2+
3+
// `--with-derive-default` is added by the test runner implicitly.
4+
5+
class NoDefault {
6+
int x;
7+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// bindgen-flags: --no-default "NoDefault" --whitelist-type "NoDefault"
2+
3+
// `--with-derive-default` is added by the test runner implicitly.
4+
5+
class NoDefault {
6+
int x;
7+
};

tests/headers/no-default.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// bindgen-flags: --no-default "NotDefault"
2+
3+
// `--with-derive-default` is added by the test runner implicitly.
4+
5+
class NotDefault {
6+
int x;
7+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// bindgen-flags: --no-default "NoDefault" --whitelist-type "Whitelisted"
2+
3+
// `--with-derive-default` is added by the test runner implicitly.
4+
5+
struct NoDefault {};
6+
7+
class Whitelisted {
8+
NoDefault x;
9+
};

0 commit comments

Comments
 (0)