From f96dcf97f09182093bc7b82cd5f9b388e89afc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 3 Feb 2020 12:03:15 +0100 Subject: [PATCH] options: Add an opt-in to recover the size_t behavior removed in 5d38f2ac. --- src/codegen/mod.rs | 6 +++ src/lib.rs | 14 ++++++ src/options.rs | 7 +++ tests/expectations/tests/size_t_is_usize.rs | 49 +++++++++++++++++++++ tests/headers/size_t_is_usize.h | 10 +++++ 5 files changed, 86 insertions(+) create mode 100644 tests/expectations/tests/size_t_is_usize.rs create mode 100644 tests/headers/size_t_is_usize.h diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index ab62b13577..9a3b10d70b 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -4126,8 +4126,14 @@ mod utils { "int64_t" => primitive_ty(ctx, "i64"), "uint64_t" => primitive_ty(ctx, "u64"), + "size_t" if ctx.options().size_t_is_usize => { + primitive_ty(ctx, "usize") + } "uintptr_t" => primitive_ty(ctx, "usize"), + "ssize_t" if ctx.options().size_t_is_usize => { + primitive_ty(ctx, "isize") + } "intptr_t" | "ptrdiff_t" => primitive_ty(ctx, "isize"), _ => return None, }) diff --git a/src/lib.rs b/src/lib.rs index 97fbdf01e9..4a8b8d8a7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -604,6 +604,10 @@ impl Builder { output_vector.push("--no-record-matches".into()); } + if self.options.size_t_is_usize { + output_vector.push("--size_t-is-usize".into()); + } + if !self.options.rustfmt_bindings { output_vector.push("--no-rustfmt-bindings".into()); } @@ -1350,6 +1354,12 @@ impl Builder { self } + /// Set whether `size_t` should be translated to `usize` automatically. + pub fn size_t_is_usize(mut self, is: bool) -> Self { + self.options.size_t_is_usize = is; + self + } + /// Set whether rustfmt should format the generated bindings. pub fn rustfmt_bindings(mut self, doit: bool) -> Self { self.options.rustfmt_bindings = doit; @@ -1776,6 +1786,9 @@ struct BindgenOptions { /// items via the `error!` log. record_matches: bool, + /// Whether `size_t` should be translated to `usize` automatically. + size_t_is_usize: bool, + /// Whether rustfmt should format the generated bindings. rustfmt_bindings: bool, @@ -1917,6 +1930,7 @@ impl Default for BindgenOptions { time_phases: false, record_matches: true, rustfmt_bindings: true, + size_t_is_usize: false, rustfmt_configuration_file: None, no_partialeq_types: Default::default(), no_copy_types: Default::default(), diff --git a/src/options.rs b/src/options.rs index 01982f13cf..b630bb4bed 100644 --- a/src/options.rs +++ b/src/options.rs @@ -383,6 +383,9 @@ where "Do not record matching items in the regex sets. \ This disables reporting of unused items.", ), + Arg::with_name("size_t-is-usize") + .long("size_t-is-usize") + .help("Translate size_t to usize."), Arg::with_name("no-rustfmt-bindings") .long("no-rustfmt-bindings") .help("Do not format the generated bindings with rustfmt."), @@ -763,6 +766,10 @@ where builder = builder.record_matches(false); } + if matches.is_present("size_t-is-usize") { + builder = builder.size_t_is_usize(true); + } + let no_rustfmt_bindings = matches.is_present("no-rustfmt-bindings"); if no_rustfmt_bindings { builder = builder.rustfmt_bindings(false); diff --git a/tests/expectations/tests/size_t_is_usize.rs b/tests/expectations/tests/size_t_is_usize.rs new file mode 100644 index 0000000000..c8cd9e054f --- /dev/null +++ b/tests/expectations/tests/size_t_is_usize.rs @@ -0,0 +1,49 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + pub len: usize, + pub offset: isize, + pub next: *mut A, +} +#[test] +fn bindgen_test_layout_A() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(A)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(A)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).len as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(A), "::", stringify!(len)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).offset as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(A), "::", stringify!(offset)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).next as *const _ as usize }, + 16usize, + concat!("Offset of field: ", stringify!(A), "::", stringify!(next)) + ); +} +impl Default for A { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} diff --git a/tests/headers/size_t_is_usize.h b/tests/headers/size_t_is_usize.h new file mode 100644 index 0000000000..564b486784 --- /dev/null +++ b/tests/headers/size_t_is_usize.h @@ -0,0 +1,10 @@ +// bindgen-flags: --size_t-is-usize + +typedef unsigned long size_t; +typedef long ssize_t; + +struct A { + size_t len; + ssize_t offset; + struct A* next; +};