Skip to content

Commit e1b3828

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 c6a798e commit e1b3828

14 files changed

+251
-0
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
@@ -2627,6 +2627,12 @@ If you encounter an error missing from this list, please file an issue or a PR!"
26272627
let name = item.path_for_whitelisting(self)[1..].join("::");
26282628
self.options().no_hash_types.matches(&name)
26292629
}
2630+
2631+
/// Check if `--no-default` flag is enabled for this item.
2632+
pub fn no_default_by_name(&self, item: &Item) -> bool {
2633+
let name = item.path_for_whitelisting(self)[1..].join("::");
2634+
self.options().no_default_types.matches(&name)
2635+
}
26302636
}
26312637

26322638
/// 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
@@ -586,6 +586,16 @@ impl Builder {
586586
})
587587
.count();
588588

589+
self.options
590+
.no_default_types
591+
.get_items()
592+
.iter()
593+
.map(|item| {
594+
output_vector.push("--no-default".into());
595+
output_vector.push(item.to_owned());
596+
})
597+
.count();
598+
589599
output_vector
590600
}
591601

@@ -1361,6 +1371,13 @@ impl Builder {
13611371
self.options.array_pointers_in_arguments = doit;
13621372
self
13631373
}
1374+
1375+
/// Don't derive `Default` for a given type. Regular
1376+
/// expressions are supported.
1377+
pub fn no_default<T: Into<String>>(mut self, arg: T) -> Builder {
1378+
self.options.no_default_types.insert(arg.into());
1379+
self
1380+
}
13641381
}
13651382

13661383
/// Configuration options for generated bindings.
@@ -1600,6 +1617,9 @@ struct BindgenOptions {
16001617

16011618
/// Decide if C arrays should be regular pointers in rust or array pointers
16021619
array_pointers_in_arguments: bool,
1620+
1621+
/// The set of types that we should not derive `Default` for.
1622+
no_default_types: RegexSet,
16031623
}
16041624

16051625
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1625,6 +1645,7 @@ impl BindgenOptions {
16251645
&mut self.no_partialeq_types,
16261646
&mut self.no_copy_types,
16271647
&mut self.no_hash_types,
1648+
&mut self.no_default_types,
16281649
];
16291650
let record_matches = self.record_matches;
16301651
for regex_set in &mut regex_sets {
@@ -1715,6 +1736,7 @@ impl Default for BindgenOptions {
17151736
no_copy_types: Default::default(),
17161737
no_hash_types: Default::default(),
17171738
array_pointers_in_arguments: false,
1739+
no_default_types: Default::default(),
17181740
}
17191741
}
17201742
}

src/options.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,13 @@ where
378378
Arg::with_name("use-array-pointers-in-arguments")
379379
.long("use-array-pointers-in-arguments")
380380
.help("Use `*const [T; size]` instead of `*const T` for C arrays"),
381+
Arg::with_name("no-default")
382+
.long("no-default")
383+
.help("Avoids deriving Default for types matching <regex>.")
384+
.value_name("regex")
385+
.takes_value(true)
386+
.multiple(true)
387+
.number_of_values(1),
381388
]) // .args()
382389
.get_matches_from(args);
383390

@@ -713,6 +720,12 @@ where
713720
}
714721
}
715722

723+
if let Some(no_default) = matches.values_of("no-default") {
724+
for regex in no_default {
725+
builder = builder.no_default(regex);
726+
}
727+
}
728+
716729
let verbose = matches.is_present("verbose");
717730

718731
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)