diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index f47787afc7..4697ba213b 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1493,7 +1493,9 @@ impl CodeGenerator for CompInfo { needs_default_impl = ctx.options().derive_default; } - if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() { + if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() && + ctx.options().derive_copy + { derives.push("Copy"); if used_template_params.is_some() { // FIXME: This requires extra logic if you have a big array in a diff --git a/src/lib.rs b/src/lib.rs index af50f0e9c2..91b7d8d424 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -253,6 +253,10 @@ impl Builder { output_vector.push("--no-layout-tests".into()); } + if !self.options.derive_copy { + output_vector.push("--no-derive-copy".into()); + } + if !self.options.derive_debug { output_vector.push("--no-derive-debug".into()); } @@ -735,6 +739,12 @@ impl Builder { self } + /// Set whether `Copy` should be derived by default. + pub fn derive_copy(mut self, doit: bool) -> Self { + self.options.derive_copy = doit; + self + } + /// Set whether `Debug` should be derived by default. pub fn derive_debug(mut self, doit: bool) -> Self { self.options.derive_debug = doit; @@ -1104,6 +1114,10 @@ pub struct BindgenOptions { /// True if we should generate layout tests for generated structures. pub layout_tests: bool, + /// True if we should derive Copy trait implementations for C/C++ structures + /// and types. + pub derive_copy: bool, + /// True if we should derive Debug trait implementations for C/C++ structures /// and types. pub derive_debug: bool, @@ -1269,6 +1283,7 @@ impl Default for BindgenOptions { emit_ir: false, emit_ir_graphviz: None, layout_tests: true, + derive_copy: true, derive_debug: true, impl_debug: false, derive_default: false, diff --git a/src/options.rs b/src/options.rs index c6f5c0108c..aaf3195317 100644 --- a/src/options.rs +++ b/src/options.rs @@ -61,6 +61,9 @@ where Arg::with_name("no-layout-tests") .long("no-layout-tests") .help("Avoid generating layout tests for any type."), + Arg::with_name("no-derive-copy") + .long("no-derive-copy") + .help("Avoid deriving Copy on any type."), Arg::with_name("no-derive-debug") .long("no-derive-debug") .help("Avoid deriving Debug on any type."), @@ -311,6 +314,10 @@ where builder = builder.layout_tests(false); } + if matches.is_present("no-derive-copy") { + builder = builder.derive_copy(false); + } + if matches.is_present("no-derive-debug") { builder = builder.derive_debug(false); } diff --git a/tests/expectations/tests/do-not-derive-copy.rs b/tests/expectations/tests/do-not-derive-copy.rs new file mode 100644 index 0000000000..114b73e398 --- /dev/null +++ b/tests/expectations/tests/do-not-derive-copy.rs @@ -0,0 +1,28 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + + +#[repr(C)] +#[derive(Debug, Default)] +pub struct WouldBeCopyButWeAreNotDerivingCopy { + pub x: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_WouldBeCopyButWeAreNotDerivingCopy() { + assert_eq!(::std::mem::size_of::() , + 4usize , concat ! ( + "Size of: " , stringify ! ( WouldBeCopyButWeAreNotDerivingCopy + ) )); + assert_eq! (::std::mem::align_of::() , + 4usize , concat ! ( + "Alignment of " , stringify ! ( + WouldBeCopyButWeAreNotDerivingCopy ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const WouldBeCopyButWeAreNotDerivingCopy ) ) . + x as * const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( + WouldBeCopyButWeAreNotDerivingCopy ) , "::" , stringify ! ( x + ) )); +} diff --git a/tests/headers/do-not-derive-copy.hpp b/tests/headers/do-not-derive-copy.hpp new file mode 100644 index 0000000000..18c2613540 --- /dev/null +++ b/tests/headers/do-not-derive-copy.hpp @@ -0,0 +1,5 @@ +// bindgen-flags: --no-derive-copy + +class WouldBeCopyButWeAreNotDerivingCopy { + int x; +};