diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 52dfdbe56f..20151fe3e5 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -986,6 +986,9 @@ impl CodeGenerator for TemplateInstantiation { // Although uses of instantiations don't need code generation, and are // just converted to rust types in fields, vars, etc, we take this // opportunity to generate tests for their layout here. + if !ctx.options().layout_tests { + return + } let layout = item.kind().expect_type().layout(ctx); @@ -1498,76 +1501,78 @@ impl CodeGenerator for CompInfo { .codegen(ctx, result, whitelisted_items, &()); } - if let Some(layout) = layout { - let fn_name = format!("bindgen_test_layout_{}", canonical_name); - let fn_name = ctx.rust_ident_raw(&fn_name); - let type_name = ctx.rust_ident_raw(&canonical_name); - let prefix = ctx.trait_prefix(); - let size_of_expr = quote_expr!(ctx.ext_cx(), - ::$prefix::mem::size_of::<$type_name>()); - let align_of_expr = quote_expr!(ctx.ext_cx(), - ::$prefix::mem::align_of::<$type_name>()); - let size = layout.size; - let align = layout.align; - - let check_struct_align = if align > mem::size_of::<*mut ()>() { - // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready - None - } else { - quote_item!(ctx.ext_cx(), - assert_eq!($align_of_expr, - $align, - concat!("Alignment of ", stringify!($type_name))); - ) - }; + if ctx.options().layout_tests { + if let Some(layout) = layout { + let fn_name = format!("bindgen_test_layout_{}", canonical_name); + let fn_name = ctx.rust_ident_raw(&fn_name); + let type_name = ctx.rust_ident_raw(&canonical_name); + let prefix = ctx.trait_prefix(); + let size_of_expr = quote_expr!(ctx.ext_cx(), + ::$prefix::mem::size_of::<$type_name>()); + let align_of_expr = quote_expr!(ctx.ext_cx(), + ::$prefix::mem::align_of::<$type_name>()); + let size = layout.size; + let align = layout.align; + + let check_struct_align = if align > mem::size_of::<*mut ()>() { + // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready + None + } else { + quote_item!(ctx.ext_cx(), + assert_eq!($align_of_expr, + $align, + concat!("Alignment of ", stringify!($type_name))); + ) + }; - // FIXME when [issue #465](https://github.com/servo/rust-bindgen/issues/465) ready - let too_many_base_vtables = self.base_members() - .iter() - .filter(|base| { - ctx.resolve_type(base.ty).has_vtable(ctx) - }) - .count() > 1; + // FIXME when [issue #465](https://github.com/servo/rust-bindgen/issues/465) ready + let too_many_base_vtables = self.base_members() + .iter() + .filter(|base| { + ctx.resolve_type(base.ty).has_vtable(ctx) + }) + .count() > 1; - let should_skip_field_offset_checks = item.is_opaque(ctx) || - too_many_base_vtables; + let should_skip_field_offset_checks = item.is_opaque(ctx) || + too_many_base_vtables; - let check_field_offset = if should_skip_field_offset_checks { - None - } else { - let asserts = self.fields() - .iter() - .filter(|field| field.bitfield().is_none()) - .flat_map(|field| { - field.name().and_then(|name| { - field.offset().and_then(|offset| { - let field_offset = offset / 8; - let field_name = ctx.rust_ident(name); - - quote_item!(ctx.ext_cx(), - assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize }, - $field_offset, - concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name))); - ) + let check_field_offset = if should_skip_field_offset_checks { + None + } else { + let asserts = self.fields() + .iter() + .filter(|field| field.bitfield().is_none()) + .flat_map(|field| { + field.name().and_then(|name| { + field.offset().and_then(|offset| { + let field_offset = offset / 8; + let field_name = ctx.rust_ident(name); + + quote_item!(ctx.ext_cx(), + assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize }, + $field_offset, + concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name))); + ) + }) }) - }) - }).collect::>>(); + }).collect::>>(); - Some(asserts) - }; + Some(asserts) + }; - let item = quote_item!(ctx.ext_cx(), - #[test] - fn $fn_name() { - assert_eq!($size_of_expr, - $size, - concat!("Size of: ", stringify!($type_name))); + let item = quote_item!(ctx.ext_cx(), + #[test] + fn $fn_name() { + assert_eq!($size_of_expr, + $size, + concat!("Size of: ", stringify!($type_name))); - $check_struct_align - $check_field_offset - }) - .unwrap(); - result.push(item); + $check_struct_align + $check_field_offset + }) + .unwrap(); + result.push(item); + } } let mut method_names = Default::default(); diff --git a/src/lib.rs b/src/lib.rs index 31c0fc1723..5960d61602 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -214,29 +214,33 @@ impl Builder { }) .count(); - if self.options.derive_debug == false { + if !self.options.layout_tests { + output_vector.push("--no-layout-tests".into()); + } + + if !self.options.derive_debug { output_vector.push("--no-derive-debug".into()); } - if self.options.derive_default == false { + if !self.options.derive_default { output_vector.push("--no-derive-default".into()); } else { output_vector.push("--with-derive-default".into()); } - if self.options.generate_comments == false { + if !self.options.generate_comments { output_vector.push("--no-doc-comments".into()); } - if self.options.whitelist_recursively == false { + if !self.options.whitelist_recursively { output_vector.push("--no-recursive-whitelist".into()); } - if self.options.objc_extern_crate == true { + if self.options.objc_extern_crate { output_vector.push("--objc-extern-crate".into()); } - if self.options.builtins == true { + if self.options.builtins { output_vector.push("--builtins".into()); } @@ -259,21 +263,21 @@ impl Builder { output_vector.push(dummy.clone()); } - if self.options.emit_ast == true { + if self.options.emit_ast { output_vector.push("--emit-clang-ast".into()); } - if self.options.emit_ir == true { + if self.options.emit_ir { output_vector.push("--emit-ir".into()); } if let Some(ref graph) = self.options.emit_ir_graphviz { output_vector.push("--emit-ir-graphviz".into()); output_vector.push(graph.clone()) } - if self.options.enable_cxx_namespaces == true { + if self.options.enable_cxx_namespaces { output_vector.push("--enable-cxx-namespaces".into()); } - if self.options.disable_name_namespacing == true { + if self.options.disable_name_namespacing { output_vector.push("--disable-name-namespacing".into()); } @@ -286,7 +290,7 @@ impl Builder { }) .count(); - if self.options.codegen_config.functions == false { + if !self.options.codegen_config.functions { output_vector.push("--ignore-functions".into()); } @@ -294,28 +298,28 @@ impl Builder { //Temporary placeholder for below 4 options let mut options:Vec = Vec::new(); - if self.options.codegen_config.functions == true { + if self.options.codegen_config.functions { options.push("function".into()); } - if self.options.codegen_config.types == true { + if self.options.codegen_config.types { options.push("types".into()); } - if self.options.codegen_config.vars == true { + if self.options.codegen_config.vars { options.push("vars".into()); } - if self.options.codegen_config.methods == true { + if self.options.codegen_config.methods { options.push("methods".into()); } - if self.options.codegen_config.constructors == true { + if self.options.codegen_config.constructors { options.push("constructors".into()); } - if self.options.codegen_config.destructors == true { + if self.options.codegen_config.destructors { options.push("destructors".into()); } output_vector.push(options.join(",")); - if self.options.codegen_config.methods == false{ + if !self.options.codegen_config.methods { output_vector.push("--ignore-methods".into()); } @@ -328,15 +332,15 @@ impl Builder { }) .count(); - if self.options.convert_floats == false { + if !self.options.convert_floats { output_vector.push("--no-convert-floats".into()); } - if self.options.prepend_enum_name == false { + if !self.options.prepend_enum_name { output_vector.push("--no-prepend-enum-name".into()); } - if self.options.unstable_rust == false { + if !self.options.unstable_rust { output_vector.push("--no-unstable-rust".into()); } @@ -368,11 +372,11 @@ impl Builder { }) .count(); - if self.options.use_core == true { + if self.options.use_core { output_vector.push("--use-core".into()); } - if self.options.conservative_inline_namespaces == true { + if self.options.conservative_inline_namespaces { output_vector.push("--conservative-inline-namespaces".into()); } @@ -582,6 +586,12 @@ impl Builder { self } + /// Set whether layout tests should be generated. + pub fn layout_tests(mut self, doit: bool) -> Self { + self.options.layout_tests = doit; + self + } + /// Set whether `Debug` should be derived by default. pub fn derive_debug(mut self, doit: bool) -> Self { self.options.derive_debug = doit; @@ -785,11 +795,14 @@ pub struct BindgenOptions { /// True if we should avoid mangling names with namespaces. pub disable_name_namespacing: bool, - /// True if we shold derive Debug trait implementations for C/C++ structures + /// True if we should generate layout tests for generated structures. + pub layout_tests: bool, + + /// True if we should derive Debug trait implementations for C/C++ structures /// and types. pub derive_debug: bool, - /// True if we shold derive Default trait implementations for C/C++ structures + /// True if we should derive Default trait implementations for C/C++ structures /// and types. pub derive_default: bool, @@ -901,6 +914,7 @@ impl Default for BindgenOptions { emit_ast: false, emit_ir: false, emit_ir_graphviz: None, + layout_tests: true, derive_debug: true, derive_default: false, enable_cxx_namespaces: false, @@ -1237,4 +1251,4 @@ fn commandline_flag_unit_test_function() { assert!(test_cases.iter().all(|ref x| command_line_flags.contains(x)) ); -} \ No newline at end of file +} diff --git a/src/options.rs b/src/options.rs index 6d06ad3b2f..9072abd820 100644 --- a/src/options.rs +++ b/src/options.rs @@ -40,6 +40,9 @@ pub fn builder_from_flags .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("no-layout-tests") + .long("no-layout-tests") + .help("Avoid generating layout tests for any type."), Arg::with_name("no-derive-debug") .long("no-derive-debug") .help("Avoid deriving Debug on any type."), @@ -233,6 +236,10 @@ pub fn builder_from_flags builder = builder.emit_builtins(); } + if matches.is_present("no-layout-tests") { + builder = builder.layout_tests(false); + } + if matches.is_present("no-derive-debug") { builder = builder.derive_debug(false); }