Skip to content

Commit 8b1f7c0

Browse files
author
bors-servo
authored
Auto merge of rust-lang#632 - dimbleby:no-layout-tests, r=fitzgen
Option to avoid generating layout tests as discussed in rust-lang#424
2 parents 3f5975e + b8dd5c9 commit 8b1f7c0

File tree

3 files changed

+115
-89
lines changed

3 files changed

+115
-89
lines changed

src/codegen/mod.rs

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,9 @@ impl CodeGenerator for TemplateInstantiation {
986986
// Although uses of instantiations don't need code generation, and are
987987
// just converted to rust types in fields, vars, etc, we take this
988988
// opportunity to generate tests for their layout here.
989+
if !ctx.options().layout_tests {
990+
return
991+
}
989992

990993
let layout = item.kind().expect_type().layout(ctx);
991994

@@ -1498,76 +1501,78 @@ impl CodeGenerator for CompInfo {
14981501
.codegen(ctx, result, whitelisted_items, &());
14991502
}
15001503

1501-
if let Some(layout) = layout {
1502-
let fn_name = format!("bindgen_test_layout_{}", canonical_name);
1503-
let fn_name = ctx.rust_ident_raw(&fn_name);
1504-
let type_name = ctx.rust_ident_raw(&canonical_name);
1505-
let prefix = ctx.trait_prefix();
1506-
let size_of_expr = quote_expr!(ctx.ext_cx(),
1507-
::$prefix::mem::size_of::<$type_name>());
1508-
let align_of_expr = quote_expr!(ctx.ext_cx(),
1509-
::$prefix::mem::align_of::<$type_name>());
1510-
let size = layout.size;
1511-
let align = layout.align;
1512-
1513-
let check_struct_align = if align > mem::size_of::<*mut ()>() {
1514-
// FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
1515-
None
1516-
} else {
1517-
quote_item!(ctx.ext_cx(),
1518-
assert_eq!($align_of_expr,
1519-
$align,
1520-
concat!("Alignment of ", stringify!($type_name)));
1521-
)
1522-
};
1504+
if ctx.options().layout_tests {
1505+
if let Some(layout) = layout {
1506+
let fn_name = format!("bindgen_test_layout_{}", canonical_name);
1507+
let fn_name = ctx.rust_ident_raw(&fn_name);
1508+
let type_name = ctx.rust_ident_raw(&canonical_name);
1509+
let prefix = ctx.trait_prefix();
1510+
let size_of_expr = quote_expr!(ctx.ext_cx(),
1511+
::$prefix::mem::size_of::<$type_name>());
1512+
let align_of_expr = quote_expr!(ctx.ext_cx(),
1513+
::$prefix::mem::align_of::<$type_name>());
1514+
let size = layout.size;
1515+
let align = layout.align;
1516+
1517+
let check_struct_align = if align > mem::size_of::<*mut ()>() {
1518+
// FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
1519+
None
1520+
} else {
1521+
quote_item!(ctx.ext_cx(),
1522+
assert_eq!($align_of_expr,
1523+
$align,
1524+
concat!("Alignment of ", stringify!($type_name)));
1525+
)
1526+
};
15231527

1524-
// FIXME when [issue #465](https://github.com/servo/rust-bindgen/issues/465) ready
1525-
let too_many_base_vtables = self.base_members()
1526-
.iter()
1527-
.filter(|base| {
1528-
ctx.resolve_type(base.ty).has_vtable(ctx)
1529-
})
1530-
.count() > 1;
1528+
// FIXME when [issue #465](https://github.com/servo/rust-bindgen/issues/465) ready
1529+
let too_many_base_vtables = self.base_members()
1530+
.iter()
1531+
.filter(|base| {
1532+
ctx.resolve_type(base.ty).has_vtable(ctx)
1533+
})
1534+
.count() > 1;
15311535

1532-
let should_skip_field_offset_checks = item.is_opaque(ctx) ||
1533-
too_many_base_vtables;
1536+
let should_skip_field_offset_checks = item.is_opaque(ctx) ||
1537+
too_many_base_vtables;
15341538

1535-
let check_field_offset = if should_skip_field_offset_checks {
1536-
None
1537-
} else {
1538-
let asserts = self.fields()
1539-
.iter()
1540-
.filter(|field| field.bitfield().is_none())
1541-
.flat_map(|field| {
1542-
field.name().and_then(|name| {
1543-
field.offset().and_then(|offset| {
1544-
let field_offset = offset / 8;
1545-
let field_name = ctx.rust_ident(name);
1546-
1547-
quote_item!(ctx.ext_cx(),
1548-
assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize },
1549-
$field_offset,
1550-
concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name)));
1551-
)
1539+
let check_field_offset = if should_skip_field_offset_checks {
1540+
None
1541+
} else {
1542+
let asserts = self.fields()
1543+
.iter()
1544+
.filter(|field| field.bitfield().is_none())
1545+
.flat_map(|field| {
1546+
field.name().and_then(|name| {
1547+
field.offset().and_then(|offset| {
1548+
let field_offset = offset / 8;
1549+
let field_name = ctx.rust_ident(name);
1550+
1551+
quote_item!(ctx.ext_cx(),
1552+
assert_eq!(unsafe { &(*(0 as *const $type_name)).$field_name as *const _ as usize },
1553+
$field_offset,
1554+
concat!("Alignment of field: ", stringify!($type_name), "::", stringify!($field_name)));
1555+
)
1556+
})
15521557
})
1553-
})
1554-
}).collect::<Vec<P<ast::Item>>>();
1558+
}).collect::<Vec<P<ast::Item>>>();
15551559

1556-
Some(asserts)
1557-
};
1560+
Some(asserts)
1561+
};
15581562

1559-
let item = quote_item!(ctx.ext_cx(),
1560-
#[test]
1561-
fn $fn_name() {
1562-
assert_eq!($size_of_expr,
1563-
$size,
1564-
concat!("Size of: ", stringify!($type_name)));
1563+
let item = quote_item!(ctx.ext_cx(),
1564+
#[test]
1565+
fn $fn_name() {
1566+
assert_eq!($size_of_expr,
1567+
$size,
1568+
concat!("Size of: ", stringify!($type_name)));
15651569

1566-
$check_struct_align
1567-
$check_field_offset
1568-
})
1569-
.unwrap();
1570-
result.push(item);
1570+
$check_struct_align
1571+
$check_field_offset
1572+
})
1573+
.unwrap();
1574+
result.push(item);
1575+
}
15711576
}
15721577

15731578
let mut method_names = Default::default();

src/lib.rs

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -214,29 +214,33 @@ impl Builder {
214214
})
215215
.count();
216216

217-
if self.options.derive_debug == false {
217+
if !self.options.layout_tests {
218+
output_vector.push("--no-layout-tests".into());
219+
}
220+
221+
if !self.options.derive_debug {
218222
output_vector.push("--no-derive-debug".into());
219223
}
220224

221-
if self.options.derive_default == false {
225+
if !self.options.derive_default {
222226
output_vector.push("--no-derive-default".into());
223227
} else {
224228
output_vector.push("--with-derive-default".into());
225229
}
226230

227-
if self.options.generate_comments == false {
231+
if !self.options.generate_comments {
228232
output_vector.push("--no-doc-comments".into());
229233
}
230234

231-
if self.options.whitelist_recursively == false {
235+
if !self.options.whitelist_recursively {
232236
output_vector.push("--no-recursive-whitelist".into());
233237
}
234238

235-
if self.options.objc_extern_crate == true {
239+
if self.options.objc_extern_crate {
236240
output_vector.push("--objc-extern-crate".into());
237241
}
238242

239-
if self.options.builtins == true {
243+
if self.options.builtins {
240244
output_vector.push("--builtins".into());
241245
}
242246

@@ -259,21 +263,21 @@ impl Builder {
259263
output_vector.push(dummy.clone());
260264
}
261265

262-
if self.options.emit_ast == true {
266+
if self.options.emit_ast {
263267
output_vector.push("--emit-clang-ast".into());
264268
}
265269

266-
if self.options.emit_ir == true {
270+
if self.options.emit_ir {
267271
output_vector.push("--emit-ir".into());
268272
}
269273
if let Some(ref graph) = self.options.emit_ir_graphviz {
270274
output_vector.push("--emit-ir-graphviz".into());
271275
output_vector.push(graph.clone())
272276
}
273-
if self.options.enable_cxx_namespaces == true {
277+
if self.options.enable_cxx_namespaces {
274278
output_vector.push("--enable-cxx-namespaces".into());
275279
}
276-
if self.options.disable_name_namespacing == true {
280+
if self.options.disable_name_namespacing {
277281
output_vector.push("--disable-name-namespacing".into());
278282
}
279283

@@ -286,36 +290,36 @@ impl Builder {
286290
})
287291
.count();
288292

289-
if self.options.codegen_config.functions == false {
293+
if !self.options.codegen_config.functions {
290294
output_vector.push("--ignore-functions".into());
291295
}
292296

293297
output_vector.push("--generate".into());
294298

295299
//Temporary placeholder for below 4 options
296300
let mut options:Vec<String> = Vec::new();
297-
if self.options.codegen_config.functions == true {
301+
if self.options.codegen_config.functions {
298302
options.push("function".into());
299303
}
300-
if self.options.codegen_config.types == true {
304+
if self.options.codegen_config.types {
301305
options.push("types".into());
302306
}
303-
if self.options.codegen_config.vars == true {
307+
if self.options.codegen_config.vars {
304308
options.push("vars".into());
305309
}
306-
if self.options.codegen_config.methods == true {
310+
if self.options.codegen_config.methods {
307311
options.push("methods".into());
308312
}
309-
if self.options.codegen_config.constructors == true {
313+
if self.options.codegen_config.constructors {
310314
options.push("constructors".into());
311315
}
312-
if self.options.codegen_config.destructors == true {
316+
if self.options.codegen_config.destructors {
313317
options.push("destructors".into());
314318
}
315319

316320
output_vector.push(options.join(","));
317321

318-
if self.options.codegen_config.methods == false{
322+
if !self.options.codegen_config.methods {
319323
output_vector.push("--ignore-methods".into());
320324
}
321325

@@ -328,15 +332,15 @@ impl Builder {
328332
})
329333
.count();
330334

331-
if self.options.convert_floats == false {
335+
if !self.options.convert_floats {
332336
output_vector.push("--no-convert-floats".into());
333337
}
334338

335-
if self.options.prepend_enum_name == false {
339+
if !self.options.prepend_enum_name {
336340
output_vector.push("--no-prepend-enum-name".into());
337341
}
338342

339-
if self.options.unstable_rust == false {
343+
if !self.options.unstable_rust {
340344
output_vector.push("--no-unstable-rust".into());
341345
}
342346

@@ -368,11 +372,11 @@ impl Builder {
368372
})
369373
.count();
370374

371-
if self.options.use_core == true {
375+
if self.options.use_core {
372376
output_vector.push("--use-core".into());
373377
}
374378

375-
if self.options.conservative_inline_namespaces == true {
379+
if self.options.conservative_inline_namespaces {
376380
output_vector.push("--conservative-inline-namespaces".into());
377381
}
378382

@@ -582,6 +586,12 @@ impl Builder {
582586
self
583587
}
584588

589+
/// Set whether layout tests should be generated.
590+
pub fn layout_tests(mut self, doit: bool) -> Self {
591+
self.options.layout_tests = doit;
592+
self
593+
}
594+
585595
/// Set whether `Debug` should be derived by default.
586596
pub fn derive_debug(mut self, doit: bool) -> Self {
587597
self.options.derive_debug = doit;
@@ -785,11 +795,14 @@ pub struct BindgenOptions {
785795
/// True if we should avoid mangling names with namespaces.
786796
pub disable_name_namespacing: bool,
787797

788-
/// True if we shold derive Debug trait implementations for C/C++ structures
798+
/// True if we should generate layout tests for generated structures.
799+
pub layout_tests: bool,
800+
801+
/// True if we should derive Debug trait implementations for C/C++ structures
789802
/// and types.
790803
pub derive_debug: bool,
791804

792-
/// True if we shold derive Default trait implementations for C/C++ structures
805+
/// True if we should derive Default trait implementations for C/C++ structures
793806
/// and types.
794807
pub derive_default: bool,
795808

@@ -901,6 +914,7 @@ impl Default for BindgenOptions {
901914
emit_ast: false,
902915
emit_ir: false,
903916
emit_ir_graphviz: None,
917+
layout_tests: true,
904918
derive_debug: true,
905919
derive_default: false,
906920
enable_cxx_namespaces: false,
@@ -1237,4 +1251,4 @@ fn commandline_flag_unit_test_function() {
12371251

12381252
assert!(test_cases.iter().all(|ref x| command_line_flags.contains(x)) );
12391253

1240-
}
1254+
}

src/options.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ pub fn builder_from_flags<I>
4040
.takes_value(true)
4141
.multiple(true)
4242
.number_of_values(1),
43+
Arg::with_name("no-layout-tests")
44+
.long("no-layout-tests")
45+
.help("Avoid generating layout tests for any type."),
4346
Arg::with_name("no-derive-debug")
4447
.long("no-derive-debug")
4548
.help("Avoid deriving Debug on any type."),
@@ -233,6 +236,10 @@ pub fn builder_from_flags<I>
233236
builder = builder.emit_builtins();
234237
}
235238

239+
if matches.is_present("no-layout-tests") {
240+
builder = builder.layout_tests(false);
241+
}
242+
236243
if matches.is_present("no-derive-debug") {
237244
builder = builder.derive_debug(false);
238245
}

0 commit comments

Comments
 (0)