From 5f1e94a516aac89fe97ec593d5eb96169e628ebd Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 20 May 2019 13:54:50 +0300 Subject: [PATCH 1/5] Added array_pointers to the builder --- src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 45944c1daa..1f460b067a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1310,6 +1310,12 @@ impl Builder { self.options.no_hash_types.insert(arg.into()); self } + + /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut) + pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self { + self.options.array_pointers_in_arguments = doit; + self + } } /// Configuration options for generated bindings. @@ -1544,6 +1550,9 @@ struct BindgenOptions { /// The set of types that we should not derive `Hash` for. no_hash_types: RegexSet, + + /// Decide if C arrays should be regular pointers in rust or array pointers + array_pointers_in_arguments: bool, } /// TODO(emilio): This is sort of a lie (see the error message that results from @@ -1656,6 +1665,7 @@ impl Default for BindgenOptions { no_partialeq_types: Default::default(), no_copy_types: Default::default(), no_hash_types: Default::default(), + array_pointers_in_arguments: false, } } } From b6cfdd8373d465beed3f413423ff71bde6b95d87 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 20 May 2019 13:55:12 +0300 Subject: [PATCH 2/5] Added array pointers codegen --- src/codegen/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 289edf8903..788ccda29d 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3908,9 +3908,13 @@ mod utils { // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html let arg_ty = match *arg_ty.canonical_type(ctx).kind() { TypeKind::Array(t, _) => { - t.to_rust_ty_or_opaque(ctx, &()) - .to_ptr(ctx.resolve_type(t).is_const()) - }, + let stream = if ctx.options().array_pointers_in_arguments { + (*arg_ty).to_rust_ty_or_opaque(ctx, &arg_item) + } else { + t.to_rust_ty_or_opaque(ctx, &()) + }; + stream.to_ptr(ctx.resolve_type(t).is_const()) + } TypeKind::Pointer(inner) => { let inner = ctx.resolve_item(inner); let inner_ty = inner.expect_type(); From 27ee59b9aa95c4ee52858dc4ff26aa14cb2dae7f Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 20 May 2019 15:56:03 +0300 Subject: [PATCH 3/5] Added array pointers to the CLI --- src/codegen/mod.rs | 2 +- src/lib.rs | 4 ++++ src/options.rs | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 788ccda29d..84642064e6 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3909,7 +3909,7 @@ mod utils { let arg_ty = match *arg_ty.canonical_type(ctx).kind() { TypeKind::Array(t, _) => { let stream = if ctx.options().array_pointers_in_arguments { - (*arg_ty).to_rust_ty_or_opaque(ctx, &arg_item) + arg_ty.to_rust_ty_or_opaque(ctx, &arg_item) } else { t.to_rust_ty_or_opaque(ctx, &()) }; diff --git a/src/lib.rs b/src/lib.rs index 1f460b067a..a9ed7ef549 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -444,6 +444,10 @@ impl Builder { output_vector.push("--no-prepend-enum-name".into()); } + if self.options.array_pointers_in_arguments { + output_vector.push("--use-array-pointers-in-arguments".into()); + } + self.options .opaque_types .get_items() diff --git a/src/options.rs b/src/options.rs index 64de93cc43..f5ced97c4e 100644 --- a/src/options.rs +++ b/src/options.rs @@ -326,6 +326,9 @@ where .long("enable-function-attribute-detection") .help("Enables detecting unexposed attributes in functions (slow). Used to generate #[must_use] annotations."), + Arg::with_name("use-array-pointers-in-arguments") + .long("use-array-pointers-in-arguments") + .help("Use `*const [T; size]` instead of `*const T` for C arrays"), ]) // .args() .get_matches_from(args); @@ -458,6 +461,10 @@ where builder = builder.time_phases(true); } + if matches.is_present("use-array-pointers-in-arguments") { + builder = builder.array_pointers_in_arguments(true); + } + if let Some(prefix) = matches.value_of("ctypes-prefix") { builder = builder.ctypes_prefix(prefix); } From d03960a041a7724dee000b17da5de6c70cd7ad18 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 20 May 2019 15:56:36 +0300 Subject: [PATCH 4/5] Added tests for array pointers --- .../tests/with_array_pointers_arguments.rs | 21 +++++++++++++++++++ .../tests/without_array_pointers_arguments.rs | 21 +++++++++++++++++++ tests/headers/with_array_pointers_arguments.h | 5 +++++ .../without_array_pointers_arguments.h | 4 ++++ 4 files changed, 51 insertions(+) create mode 100644 tests/expectations/tests/with_array_pointers_arguments.rs create mode 100644 tests/expectations/tests/without_array_pointers_arguments.rs create mode 100644 tests/headers/with_array_pointers_arguments.h create mode 100644 tests/headers/without_array_pointers_arguments.h diff --git a/tests/expectations/tests/with_array_pointers_arguments.rs b/tests/expectations/tests/with_array_pointers_arguments.rs new file mode 100644 index 0000000000..eb3300e2dc --- /dev/null +++ b/tests/expectations/tests/with_array_pointers_arguments.rs @@ -0,0 +1,21 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +extern "C" { + pub fn test_fn( + a: f32, + arr: *mut [::std::os::raw::c_int; 20usize], + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn test_fn2( + arr: *const [f32; 20usize], + b: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} \ No newline at end of file diff --git a/tests/expectations/tests/without_array_pointers_arguments.rs b/tests/expectations/tests/without_array_pointers_arguments.rs new file mode 100644 index 0000000000..a8d9990a41 --- /dev/null +++ b/tests/expectations/tests/without_array_pointers_arguments.rs @@ -0,0 +1,21 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +extern "C" { + pub fn test_fn( + a: f32, + arr: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn test_fn2( + arr: *const f32, + b: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} \ No newline at end of file diff --git a/tests/headers/with_array_pointers_arguments.h b/tests/headers/with_array_pointers_arguments.h new file mode 100644 index 0000000000..34f669d054 --- /dev/null +++ b/tests/headers/with_array_pointers_arguments.h @@ -0,0 +1,5 @@ +// bindgen-flags: --use-array-pointers-in-arguments + +int test_fn(float a, int arr[20]); + +int test_fn2(const float arr[20], int b); \ No newline at end of file diff --git a/tests/headers/without_array_pointers_arguments.h b/tests/headers/without_array_pointers_arguments.h new file mode 100644 index 0000000000..9028c43d5d --- /dev/null +++ b/tests/headers/without_array_pointers_arguments.h @@ -0,0 +1,4 @@ + +int test_fn(float a, int arr[20]); + +int test_fn2(const float arr[20], int b); \ No newline at end of file From e0efd59d256084da85c6e6fad48a28431df18cb2 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 22 May 2019 11:27:56 +0300 Subject: [PATCH 5/5] Added tests with typedef for array pointers --- .../tests/with_array_pointers_arguments.rs | 17 ++++++++--------- .../tests/without_array_pointers_arguments.rs | 17 ++++++++--------- tests/headers/with_array_pointers_arguments.h | 7 ++++++- .../headers/without_array_pointers_arguments.h | 7 ++++++- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/tests/expectations/tests/with_array_pointers_arguments.rs b/tests/expectations/tests/with_array_pointers_arguments.rs index eb3300e2dc..3808e18be4 100644 --- a/tests/expectations/tests/with_array_pointers_arguments.rs +++ b/tests/expectations/tests/with_array_pointers_arguments.rs @@ -8,14 +8,13 @@ )] extern "C" { - pub fn test_fn( - a: f32, - arr: *mut [::std::os::raw::c_int; 20usize], - ) -> ::std::os::raw::c_int; + pub fn test_fn(a: f32, arr: *mut [::std::os::raw::c_int; 20usize]) -> ::std::os::raw::c_int; } extern "C" { - pub fn test_fn2( - arr: *const [f32; 20usize], - b: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; -} \ No newline at end of file + pub fn test_fn2(arr: *const [f32; 20usize], b: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +pub type defArr = [::std::os::raw::c_char; 20usize]; +pub type foo = ::std::option::Option; +extern "C" { + pub fn bar(a: *mut defArr); +} diff --git a/tests/expectations/tests/without_array_pointers_arguments.rs b/tests/expectations/tests/without_array_pointers_arguments.rs index a8d9990a41..b616893707 100644 --- a/tests/expectations/tests/without_array_pointers_arguments.rs +++ b/tests/expectations/tests/without_array_pointers_arguments.rs @@ -8,14 +8,13 @@ )] extern "C" { - pub fn test_fn( - a: f32, - arr: *mut ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn test_fn(a: f32, arr: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; } extern "C" { - pub fn test_fn2( - arr: *const f32, - b: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; -} \ No newline at end of file + pub fn test_fn2(arr: *const f32, b: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +pub type defArr = [::std::os::raw::c_char; 20usize]; +pub type foo = ::std::option::Option; +extern "C" { + pub fn bar(a: *mut ::std::os::raw::c_char); +} diff --git a/tests/headers/with_array_pointers_arguments.h b/tests/headers/with_array_pointers_arguments.h index 34f669d054..565b3cf678 100644 --- a/tests/headers/with_array_pointers_arguments.h +++ b/tests/headers/with_array_pointers_arguments.h @@ -2,4 +2,9 @@ int test_fn(float a, int arr[20]); -int test_fn2(const float arr[20], int b); \ No newline at end of file +int test_fn2(const float arr[20], int b); + +typedef char defArr[20]; +typedef void foo(defArr a); + +void bar(defArr a); \ No newline at end of file diff --git a/tests/headers/without_array_pointers_arguments.h b/tests/headers/without_array_pointers_arguments.h index 9028c43d5d..2f0668749b 100644 --- a/tests/headers/without_array_pointers_arguments.h +++ b/tests/headers/without_array_pointers_arguments.h @@ -1,4 +1,9 @@ int test_fn(float a, int arr[20]); -int test_fn2(const float arr[20], int b); \ No newline at end of file +int test_fn2(const float arr[20], int b); + +typedef char defArr[20]; +typedef void foo(defArr a); + +void bar(defArr a); \ No newline at end of file