From 32470a81d8cb5835cee42b9a7091c3465969773d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 24 Sep 2020 14:19:17 +0200 Subject: [PATCH 01/10] feat(parser,ir) Declare `ManuallyDrop` as a simplified type. --- src/bindgen/ir/ty.rs | 2 +- src/bindgen/parser.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index dcee55715..e06eaf999 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -433,7 +433,7 @@ impl Type { is_nullable: false, is_ref: false, }), - "Cell" => Some(generic), + "Cell" | "ManuallyDrop" => Some(generic), _ => None, } } diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index 4cf4521b7..fc9294855 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -392,6 +392,7 @@ impl Parse { add_opaque("BTreeSet", vec!["T"]); add_opaque("LinkedList", vec!["T"]); add_opaque("VecDeque", vec!["T"]); + add_opaque("ManuallyDrop", vec!["T"]); } pub fn extend_with(&mut self, other: &Parse) { From 4e37d2635310d3a1d8ccbe3498ca12dde995046c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 24 Sep 2020 14:20:22 +0200 Subject: [PATCH 02/10] test: Test `ManuallyDrop` as a simplified type. --- tests/expectations/both/manuallydrop.c | 21 ++++++++++++++ tests/expectations/both/manuallydrop.compat.c | 29 +++++++++++++++++++ tests/expectations/manuallydrop.c | 21 ++++++++++++++ tests/expectations/manuallydrop.compat.c | 29 +++++++++++++++++++ tests/expectations/manuallydrop.cpp | 29 +++++++++++++++++++ tests/expectations/tag/manuallydrop.c | 21 ++++++++++++++ tests/expectations/tag/manuallydrop.compat.c | 29 +++++++++++++++++++ tests/rust/manuallydrop.rs | 22 ++++++++++++++ 8 files changed, 201 insertions(+) create mode 100644 tests/expectations/both/manuallydrop.c create mode 100644 tests/expectations/both/manuallydrop.compat.c create mode 100644 tests/expectations/manuallydrop.c create mode 100644 tests/expectations/manuallydrop.compat.c create mode 100644 tests/expectations/manuallydrop.cpp create mode 100644 tests/expectations/tag/manuallydrop.c create mode 100644 tests/expectations/tag/manuallydrop.compat.c create mode 100644 tests/rust/manuallydrop.rs diff --git a/tests/expectations/both/manuallydrop.c b/tests/expectations/both/manuallydrop.c new file mode 100644 index 000000000..8e942facb --- /dev/null +++ b/tests/expectations/both/manuallydrop.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +typedef struct NotReprC_ManuallyDrop_Point NotReprC_ManuallyDrop_Point; + +typedef NotReprC_ManuallyDrop_Point Foo; + +typedef struct Point { + int32_t x; + int32_t y; +} Point; + +typedef struct MyStruct { + Point point; +} MyStruct; + +void root(const Foo *a, const MyStruct *with_manual_drop); + +void take(Point with_manual_drop); diff --git a/tests/expectations/both/manuallydrop.compat.c b/tests/expectations/both/manuallydrop.compat.c new file mode 100644 index 000000000..6eb3444f5 --- /dev/null +++ b/tests/expectations/both/manuallydrop.compat.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +typedef struct NotReprC_ManuallyDrop_Point NotReprC_ManuallyDrop_Point; + +typedef NotReprC_ManuallyDrop_Point Foo; + +typedef struct Point { + int32_t x; + int32_t y; +} Point; + +typedef struct MyStruct { + Point point; +} MyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(const Foo *a, const MyStruct *with_manual_drop); + +void take(Point with_manual_drop); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/manuallydrop.c b/tests/expectations/manuallydrop.c new file mode 100644 index 000000000..c4c4c2393 --- /dev/null +++ b/tests/expectations/manuallydrop.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +typedef struct NotReprC_ManuallyDrop_Point NotReprC_ManuallyDrop_Point; + +typedef NotReprC_ManuallyDrop_Point Foo; + +typedef struct { + int32_t x; + int32_t y; +} Point; + +typedef struct { + Point point; +} MyStruct; + +void root(const Foo *a, const MyStruct *with_manual_drop); + +void take(Point with_manual_drop); diff --git a/tests/expectations/manuallydrop.compat.c b/tests/expectations/manuallydrop.compat.c new file mode 100644 index 000000000..baac99a83 --- /dev/null +++ b/tests/expectations/manuallydrop.compat.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +typedef struct NotReprC_ManuallyDrop_Point NotReprC_ManuallyDrop_Point; + +typedef NotReprC_ManuallyDrop_Point Foo; + +typedef struct { + int32_t x; + int32_t y; +} Point; + +typedef struct { + Point point; +} MyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(const Foo *a, const MyStruct *with_manual_drop); + +void take(Point with_manual_drop); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/manuallydrop.cpp b/tests/expectations/manuallydrop.cpp new file mode 100644 index 000000000..2da46ec12 --- /dev/null +++ b/tests/expectations/manuallydrop.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +template +struct ManuallyDrop; + +template +struct NotReprC; + +struct Point { + int32_t x; + int32_t y; +}; + +using Foo = NotReprC>; + +struct MyStruct { + Point point; +}; + +extern "C" { + +void root(const Foo *a, const MyStruct *with_manual_drop); + +void take(Point with_manual_drop); + +} // extern "C" diff --git a/tests/expectations/tag/manuallydrop.c b/tests/expectations/tag/manuallydrop.c new file mode 100644 index 000000000..193bfbab9 --- /dev/null +++ b/tests/expectations/tag/manuallydrop.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +struct NotReprC_ManuallyDrop_Point; + +typedef struct NotReprC_ManuallyDrop_Point Foo; + +struct Point { + int32_t x; + int32_t y; +}; + +struct MyStruct { + struct Point point; +}; + +void root(const Foo *a, const struct MyStruct *with_manual_drop); + +void take(struct Point with_manual_drop); diff --git a/tests/expectations/tag/manuallydrop.compat.c b/tests/expectations/tag/manuallydrop.compat.c new file mode 100644 index 000000000..55cea1b99 --- /dev/null +++ b/tests/expectations/tag/manuallydrop.compat.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +struct NotReprC_ManuallyDrop_Point; + +typedef struct NotReprC_ManuallyDrop_Point Foo; + +struct Point { + int32_t x; + int32_t y; +}; + +struct MyStruct { + struct Point point; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(const Foo *a, const struct MyStruct *with_manual_drop); + +void take(struct Point with_manual_drop); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/rust/manuallydrop.rs b/tests/rust/manuallydrop.rs new file mode 100644 index 000000000..fea2537df --- /dev/null +++ b/tests/rust/manuallydrop.rs @@ -0,0 +1,22 @@ +#[repr(C)] +pub struct Point { + x: i32, + y: i32, +} + +#[repr(C)] +pub struct MyStruct { + point: std::mem::ManuallyDrop, +} + +pub struct NotReprC { + inner: T, +} + +pub type Foo = NotReprC>; + +#[no_mangle] +pub extern "C" fn root(a: &Foo, with_manual_drop: &MyStruct) {} + +#[no_mangle] +pub extern "C" fn take(with_manual_drop: std::mem::ManuallyDrop) {} From 94f64e7623e3bac923f647c7575d0bcdc739229b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 24 Sep 2020 14:28:26 +0200 Subject: [PATCH 03/10] feat(parser,ir) Declare `MaybeUninit` as a simplified type. --- src/bindgen/ir/ty.rs | 2 +- src/bindgen/parser.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index e06eaf999..db456b161 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -433,7 +433,7 @@ impl Type { is_nullable: false, is_ref: false, }), - "Cell" | "ManuallyDrop" => Some(generic), + "Cell" | "ManuallyDrop" | "MaybeUninit" => Some(generic), _ => None, } } diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index fc9294855..6e7695d98 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -393,6 +393,7 @@ impl Parse { add_opaque("LinkedList", vec!["T"]); add_opaque("VecDeque", vec!["T"]); add_opaque("ManuallyDrop", vec!["T"]); + add_opaque("MaybeUninit", vec!["T"]); } pub fn extend_with(&mut self, other: &Parse) { From edbd48b76af00e14b6e6de37920ae33887f4d265 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 24 Sep 2020 14:28:45 +0200 Subject: [PATCH 04/10] test: test `MaybeUninit` as a simplified type. --- tests/expectations/both/maybeuninit.c | 14 +++++++++++++ tests/expectations/both/maybeuninit.compat.c | 22 ++++++++++++++++++++ tests/expectations/maybeuninit.c | 14 +++++++++++++ tests/expectations/maybeuninit.compat.c | 22 ++++++++++++++++++++ tests/expectations/maybeuninit.cpp | 22 ++++++++++++++++++++ tests/expectations/tag/maybeuninit.c | 14 +++++++++++++ tests/expectations/tag/maybeuninit.compat.c | 22 ++++++++++++++++++++ tests/rust/maybeuninit.rs | 13 ++++++++++++ 8 files changed, 143 insertions(+) create mode 100644 tests/expectations/both/maybeuninit.c create mode 100644 tests/expectations/both/maybeuninit.compat.c create mode 100644 tests/expectations/maybeuninit.c create mode 100644 tests/expectations/maybeuninit.compat.c create mode 100644 tests/expectations/maybeuninit.cpp create mode 100644 tests/expectations/tag/maybeuninit.c create mode 100644 tests/expectations/tag/maybeuninit.compat.c create mode 100644 tests/rust/maybeuninit.rs diff --git a/tests/expectations/both/maybeuninit.c b/tests/expectations/both/maybeuninit.c new file mode 100644 index 000000000..8e87f5dc7 --- /dev/null +++ b/tests/expectations/both/maybeuninit.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +typedef struct NotReprC_MaybeUninit______i32 NotReprC_MaybeUninit______i32; + +typedef NotReprC_MaybeUninit______i32 Foo; + +typedef struct MyStruct { + const int32_t *number; +} MyStruct; + +void root(const Foo *a, const MyStruct *with_maybe_uninit); diff --git a/tests/expectations/both/maybeuninit.compat.c b/tests/expectations/both/maybeuninit.compat.c new file mode 100644 index 000000000..b3b2fa178 --- /dev/null +++ b/tests/expectations/both/maybeuninit.compat.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +typedef struct NotReprC_MaybeUninit______i32 NotReprC_MaybeUninit______i32; + +typedef NotReprC_MaybeUninit______i32 Foo; + +typedef struct MyStruct { + const int32_t *number; +} MyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(const Foo *a, const MyStruct *with_maybe_uninit); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/maybeuninit.c b/tests/expectations/maybeuninit.c new file mode 100644 index 000000000..df1b889a2 --- /dev/null +++ b/tests/expectations/maybeuninit.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +typedef struct NotReprC_MaybeUninit______i32 NotReprC_MaybeUninit______i32; + +typedef NotReprC_MaybeUninit______i32 Foo; + +typedef struct { + const int32_t *number; +} MyStruct; + +void root(const Foo *a, const MyStruct *with_maybe_uninit); diff --git a/tests/expectations/maybeuninit.compat.c b/tests/expectations/maybeuninit.compat.c new file mode 100644 index 000000000..99fadecb6 --- /dev/null +++ b/tests/expectations/maybeuninit.compat.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +typedef struct NotReprC_MaybeUninit______i32 NotReprC_MaybeUninit______i32; + +typedef NotReprC_MaybeUninit______i32 Foo; + +typedef struct { + const int32_t *number; +} MyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(const Foo *a, const MyStruct *with_maybe_uninit); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/maybeuninit.cpp b/tests/expectations/maybeuninit.cpp new file mode 100644 index 000000000..1c5febf5c --- /dev/null +++ b/tests/expectations/maybeuninit.cpp @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +template +struct MaybeUninit; + +template +struct NotReprC; + +using Foo = NotReprC>; + +struct MyStruct { + const int32_t *number; +}; + +extern "C" { + +void root(const Foo *a, const MyStruct *with_maybe_uninit); + +} // extern "C" diff --git a/tests/expectations/tag/maybeuninit.c b/tests/expectations/tag/maybeuninit.c new file mode 100644 index 000000000..246177601 --- /dev/null +++ b/tests/expectations/tag/maybeuninit.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +struct NotReprC_MaybeUninit______i32; + +typedef struct NotReprC_MaybeUninit______i32 Foo; + +struct MyStruct { + const int32_t *number; +}; + +void root(const Foo *a, const struct MyStruct *with_maybe_uninit); diff --git a/tests/expectations/tag/maybeuninit.compat.c b/tests/expectations/tag/maybeuninit.compat.c new file mode 100644 index 000000000..4e8cc8047 --- /dev/null +++ b/tests/expectations/tag/maybeuninit.compat.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +struct NotReprC_MaybeUninit______i32; + +typedef struct NotReprC_MaybeUninit______i32 Foo; + +struct MyStruct { + const int32_t *number; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(const Foo *a, const struct MyStruct *with_maybe_uninit); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/rust/maybeuninit.rs b/tests/rust/maybeuninit.rs new file mode 100644 index 000000000..e9898ce98 --- /dev/null +++ b/tests/rust/maybeuninit.rs @@ -0,0 +1,13 @@ +#[repr(C)] +pub struct MyStruct { + number: std::mem::MaybeUninit<&i32>, +} + +pub struct NotReprC { + inner: T, +} + +pub type Foo = NotReprC>; + +#[no_mangle] +pub extern "C" fn root(a: &Foo, with_maybe_uninit: &MyStruct) {} From 3c1f990b9d19aefcf1bd375252d9a740f12462a2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 28 Sep 2020 15:23:05 +0200 Subject: [PATCH 05/10] test: Lint Rust code. --- tests/rust/maybeuninit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/rust/maybeuninit.rs b/tests/rust/maybeuninit.rs index e9898ce98..807316755 100644 --- a/tests/rust/maybeuninit.rs +++ b/tests/rust/maybeuninit.rs @@ -1,13 +1,13 @@ #[repr(C)] -pub struct MyStruct { - number: std::mem::MaybeUninit<&i32>, +pub struct MyStruct<'a> { + number: std::mem::MaybeUninit<&'a i32>, } pub struct NotReprC { inner: T, } -pub type Foo = NotReprC>; +pub type Foo<'a> = NotReprC>; #[no_mangle] -pub extern "C" fn root(a: &Foo, with_maybe_uninit: &MyStruct) {} +pub extern "C" fn root<'a, 'b>(a: &'a Foo, with_maybe_uninit: &'b MyStruct) {} From 8e42a71b970bc6938594f199623bf55b58bcb14d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 28 Sep 2020 21:52:33 +0200 Subject: [PATCH 06/10] feat(ir) Simplify `ManuallyDrop` and `MaybeUninit` only for C. --- src/bindgen/ir/function.rs | 6 +++--- src/bindgen/ir/global.rs | 4 ++-- src/bindgen/ir/structure.rs | 4 ++-- src/bindgen/ir/ty.rs | 13 +++++++------ src/bindgen/ir/typedef.rs | 4 ++-- src/bindgen/ir/union.rs | 4 ++-- src/bindgen/library.rs | 12 +++++++----- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/bindgen/ir/function.rs b/src/bindgen/ir/function.rs index b9f261091..8cc746edb 100644 --- a/src/bindgen/ir/function.rs +++ b/src/bindgen/ir/function.rs @@ -120,10 +120,10 @@ impl Function { &self.path } - pub fn simplify_standard_types(&mut self) { - self.ret.simplify_standard_types(); + pub fn simplify_standard_types(&mut self, config: &Config) { + self.ret.simplify_standard_types(config); for arg in &mut self.args { - arg.ty.simplify_standard_types(); + arg.ty.simplify_standard_types(config); } } diff --git a/src/bindgen/ir/global.rs b/src/bindgen/ir/global.rs index a6ba150d6..a9d989df8 100644 --- a/src/bindgen/ir/global.rs +++ b/src/bindgen/ir/global.rs @@ -61,8 +61,8 @@ impl Static { } } - pub fn simplify_standard_types(&mut self) { - self.ty.simplify_standard_types(); + pub fn simplify_standard_types(&mut self, config: &Config) { + self.ty.simplify_standard_types(config); } } diff --git a/src/bindgen/ir/structure.rs b/src/bindgen/ir/structure.rs index e80beecd9..84e808c30 100644 --- a/src/bindgen/ir/structure.rs +++ b/src/bindgen/ir/structure.rs @@ -143,9 +143,9 @@ impl Struct { } } - pub fn simplify_standard_types(&mut self) { + pub fn simplify_standard_types(&mut self, config: &Config) { for &mut (_, ref mut ty, _) in &mut self.fields { - ty.simplify_standard_types(); + ty.simplify_standard_types(config); } } diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index db456b161..63e7d71b8 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -6,7 +6,7 @@ use std::fmt; use std::io::Write; use crate::bindgen::cdecl; -use crate::bindgen::config::Config; +use crate::bindgen::config::{Config, Language}; use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; use crate::bindgen::dependencies::Dependencies; use crate::bindgen::ir::{Documentation, GenericParams, GenericPath, Path}; @@ -411,7 +411,7 @@ impl Type { } } - fn simplified_type(&self) -> Option { + fn simplified_type(&self, config: &Config) -> Option { let path = match *self { Type::Path(ref p) => p, _ => return None, @@ -422,7 +422,7 @@ impl Type { } let mut generic = path.generics()[0].clone(); - generic.simplify_standard_types(); + generic.simplify_standard_types(config); match path.name() { // FIXME(#223): This is not quite correct. @@ -433,13 +433,14 @@ impl Type { is_nullable: false, is_ref: false, }), - "Cell" | "ManuallyDrop" | "MaybeUninit" => Some(generic), + "Cell" => Some(generic), + "ManuallyDrop" | "MaybeUninit" if config.language == Language::C => Some(generic), _ => None, } } - pub fn simplify_standard_types(&mut self) { - if let Some(ty) = self.simplified_type() { + pub fn simplify_standard_types(&mut self, config: &Config) { + if let Some(ty) = self.simplified_type(config) { *self = ty; } } diff --git a/src/bindgen/ir/typedef.rs b/src/bindgen/ir/typedef.rs index e6ae07296..18da50bbf 100644 --- a/src/bindgen/ir/typedef.rs +++ b/src/bindgen/ir/typedef.rs @@ -66,8 +66,8 @@ impl Typedef { } } - pub fn simplify_standard_types(&mut self) { - self.aliased.simplify_standard_types(); + pub fn simplify_standard_types(&mut self, config: &Config) { + self.aliased.simplify_standard_types(config); } pub fn transfer_annotations(&mut self, out: &mut HashMap) { diff --git a/src/bindgen/ir/union.rs b/src/bindgen/ir/union.rs index 6d9e2347c..089499a0a 100644 --- a/src/bindgen/ir/union.rs +++ b/src/bindgen/ir/union.rs @@ -96,9 +96,9 @@ impl Union { } } - pub fn simplify_standard_types(&mut self) { + pub fn simplify_standard_types(&mut self, config: &Config) { for &mut (_, ref mut ty, _) in &mut self.fields { - ty.simplify_standard_types(); + ty.simplify_standard_types(config); } } diff --git a/src/bindgen/library.rs b/src/bindgen/library.rs index 26c6fa3a3..fdd6e1702 100644 --- a/src/bindgen/library.rs +++ b/src/bindgen/library.rs @@ -344,20 +344,22 @@ impl Library { } fn simplify_standard_types(&mut self) { + let config = &self.config; + self.structs.for_all_items_mut(|x| { - x.simplify_standard_types(); + x.simplify_standard_types(config); }); self.unions.for_all_items_mut(|x| { - x.simplify_standard_types(); + x.simplify_standard_types(config); }); self.globals.for_all_items_mut(|x| { - x.simplify_standard_types(); + x.simplify_standard_types(config); }); self.typedefs.for_all_items_mut(|x| { - x.simplify_standard_types(); + x.simplify_standard_types(config); }); for x in &mut self.functions { - x.simplify_standard_types(); + x.simplify_standard_types(config); } } From 7571296f1929f88e24c92cc8e14eb52b1f4295b1 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 29 Sep 2020 11:03:24 +0200 Subject: [PATCH 07/10] test: Support a new `.skip_cpp` test suffix. Following the example of `.skip_warning_as_error`, this patch introduces a `.skip_cpp` suffix to skip the generation of `.cpp` files. This patch also simplifies the code. Ideally, we would create and implement a new trait offering an API like `is_cpp_skipped`, `is_warning_as_error_skipped`, and `normalize` (to remove all suffixes), but it's a little bit overkill for our needs right now. --- tests/tests.rs | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index c60da0565..0c27b32e9 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -130,6 +130,9 @@ fn compile( } } +const SKIP_CPP_SUFFIX: &'static str = ".skip_cpp"; +const SKIP_WARNING_AS_ERROR_SUFFIX: &'static str = ".skip_warning_as_error"; + fn run_compile_test( cbindgen_path: &'static str, name: &'static str, @@ -164,18 +167,14 @@ fn run_compile_test( } } }; - let skip_warning_as_error_suffix = ".skip_warning_as_error"; - let skip_warning_as_error_position = name.rfind(skip_warning_as_error_suffix); - let skip_warning_as_error = skip_warning_as_error_position.is_some(); - let mut source_file = format!("{}.{}", name, &ext); - - if skip_warning_as_error { - source_file = format!( - "{}.{}", - &name[0..skip_warning_as_error_position.unwrap()], - &ext - ); - } + + let skip_warning_as_error = name.rfind(SKIP_WARNING_AS_ERROR_SUFFIX).is_some(); + let skip_cpp = name.rfind(SKIP_CPP_SUFFIX).is_some(); + + let source_file = format!("{}.{}", &name, &ext) + .replace(SKIP_CPP_SUFFIX, "") + .replace(SKIP_WARNING_AS_ERROR_SUFFIX, ""); + generated_file.push(source_file); run_cbindgen( @@ -196,7 +195,7 @@ fn run_compile_test( skip_warning_as_error, ); - if language == Language::C && cpp_compat { + if language == Language::C && cpp_compat && !skip_cpp { compile( &generated_file, &tests_path, @@ -228,15 +227,20 @@ fn test_file(cbindgen_path: &'static str, name: &'static str, filename: &'static ); } } - run_compile_test( - cbindgen_path, - name, - &test, - tmp_dir, - Language::Cxx, - /* cpp_compat = */ false, - None, - ); + + let skip_cpp = name.rfind(SKIP_CPP_SUFFIX).is_some(); + + if !skip_cpp { + run_compile_test( + cbindgen_path, + name, + &test, + tmp_dir, + Language::Cxx, + /* cpp_compat = */ false, + None, + ); + } } macro_rules! test_file { From ece962745cbcb06d070564304c4f9de34a848e7c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 29 Sep 2020 11:07:20 +0200 Subject: [PATCH 08/10] test: Skip CPP for the `manuallydrop` and `maybeuninit` test cases. --- tests/expectations/manuallydrop.cpp | 29 ------------------- tests/expectations/maybeuninit.cpp | 22 -------------- ...nuallydrop.rs => manuallydrop.skip_cpp.rs} | 0 ...maybeuninit.rs => maybeuninit.skip_cpp.rs} | 0 4 files changed, 51 deletions(-) delete mode 100644 tests/expectations/manuallydrop.cpp delete mode 100644 tests/expectations/maybeuninit.cpp rename tests/rust/{manuallydrop.rs => manuallydrop.skip_cpp.rs} (100%) rename tests/rust/{maybeuninit.rs => maybeuninit.skip_cpp.rs} (100%) diff --git a/tests/expectations/manuallydrop.cpp b/tests/expectations/manuallydrop.cpp deleted file mode 100644 index 2da46ec12..000000000 --- a/tests/expectations/manuallydrop.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include - -template -struct ManuallyDrop; - -template -struct NotReprC; - -struct Point { - int32_t x; - int32_t y; -}; - -using Foo = NotReprC>; - -struct MyStruct { - Point point; -}; - -extern "C" { - -void root(const Foo *a, const MyStruct *with_manual_drop); - -void take(Point with_manual_drop); - -} // extern "C" diff --git a/tests/expectations/maybeuninit.cpp b/tests/expectations/maybeuninit.cpp deleted file mode 100644 index 1c5febf5c..000000000 --- a/tests/expectations/maybeuninit.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include -#include - -template -struct MaybeUninit; - -template -struct NotReprC; - -using Foo = NotReprC>; - -struct MyStruct { - const int32_t *number; -}; - -extern "C" { - -void root(const Foo *a, const MyStruct *with_maybe_uninit); - -} // extern "C" diff --git a/tests/rust/manuallydrop.rs b/tests/rust/manuallydrop.skip_cpp.rs similarity index 100% rename from tests/rust/manuallydrop.rs rename to tests/rust/manuallydrop.skip_cpp.rs diff --git a/tests/rust/maybeuninit.rs b/tests/rust/maybeuninit.skip_cpp.rs similarity index 100% rename from tests/rust/maybeuninit.rs rename to tests/rust/maybeuninit.skip_cpp.rs From d925991fd5a8fecb99c2501e88ea8d56a084378a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 29 Sep 2020 11:28:13 +0200 Subject: [PATCH 09/10] feat: Simplify `Box` to `*T` for C only. --- src/bindgen/ir/ty.rs | 10 ++++++++++ tests/expectations/both/box.c | 16 ++++++++++++++++ tests/expectations/both/box.compat.c | 24 ++++++++++++++++++++++++ tests/expectations/box.c | 16 ++++++++++++++++ tests/expectations/box.compat.c | 24 ++++++++++++++++++++++++ tests/expectations/tag/box.c | 16 ++++++++++++++++ tests/expectations/tag/box.compat.c | 24 ++++++++++++++++++++++++ tests/rust/box.skip_cpp.rs | 16 ++++++++++++++++ 8 files changed, 146 insertions(+) create mode 100644 tests/expectations/both/box.c create mode 100644 tests/expectations/both/box.compat.c create mode 100644 tests/expectations/box.c create mode 100644 tests/expectations/box.compat.c create mode 100644 tests/expectations/tag/box.c create mode 100644 tests/expectations/tag/box.compat.c create mode 100644 tests/rust/box.skip_cpp.rs diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index 63e7d71b8..a95c41303 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -433,6 +433,16 @@ impl Type { is_nullable: false, is_ref: false, }), + "Box" + if config.language == Language::C && config.function.swift_name_macro.is_none() => + { + Some(Type::Ptr { + ty: Box::new(generic), + is_const: false, + is_nullable: false, + is_ref: false, + }) + } "Cell" => Some(generic), "ManuallyDrop" | "MaybeUninit" if config.language == Language::C => Some(generic), _ => None, diff --git a/tests/expectations/both/box.c b/tests/expectations/both/box.c new file mode 100644 index 000000000..6468f86ed --- /dev/null +++ b/tests/expectations/both/box.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +typedef struct NotReprC_Box_i32 NotReprC_Box_i32; + +typedef NotReprC_Box_i32 Foo; + +typedef struct MyStruct { + int32_t *number; +} MyStruct; + +void delete(int32_t *x); + +void root(const Foo *a, const MyStruct *with_box); diff --git a/tests/expectations/both/box.compat.c b/tests/expectations/both/box.compat.c new file mode 100644 index 000000000..31f5d7a8f --- /dev/null +++ b/tests/expectations/both/box.compat.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +typedef struct NotReprC_Box_i32 NotReprC_Box_i32; + +typedef NotReprC_Box_i32 Foo; + +typedef struct MyStruct { + int32_t *number; +} MyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void delete(int32_t *x); + +void root(const Foo *a, const MyStruct *with_box); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/box.c b/tests/expectations/box.c new file mode 100644 index 000000000..967f4b7fe --- /dev/null +++ b/tests/expectations/box.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +typedef struct NotReprC_Box_i32 NotReprC_Box_i32; + +typedef NotReprC_Box_i32 Foo; + +typedef struct { + int32_t *number; +} MyStruct; + +void delete(int32_t *x); + +void root(const Foo *a, const MyStruct *with_box); diff --git a/tests/expectations/box.compat.c b/tests/expectations/box.compat.c new file mode 100644 index 000000000..4a31ac943 --- /dev/null +++ b/tests/expectations/box.compat.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +typedef struct NotReprC_Box_i32 NotReprC_Box_i32; + +typedef NotReprC_Box_i32 Foo; + +typedef struct { + int32_t *number; +} MyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void delete(int32_t *x); + +void root(const Foo *a, const MyStruct *with_box); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/tag/box.c b/tests/expectations/tag/box.c new file mode 100644 index 000000000..1667e37b2 --- /dev/null +++ b/tests/expectations/tag/box.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +struct NotReprC_Box_i32; + +typedef struct NotReprC_Box_i32 Foo; + +struct MyStruct { + int32_t *number; +}; + +void delete(int32_t *x); + +void root(const Foo *a, const struct MyStruct *with_box); diff --git a/tests/expectations/tag/box.compat.c b/tests/expectations/tag/box.compat.c new file mode 100644 index 000000000..3bf1324ec --- /dev/null +++ b/tests/expectations/tag/box.compat.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +struct NotReprC_Box_i32; + +typedef struct NotReprC_Box_i32 Foo; + +struct MyStruct { + int32_t *number; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void delete(int32_t *x); + +void root(const Foo *a, const struct MyStruct *with_box); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/rust/box.skip_cpp.rs b/tests/rust/box.skip_cpp.rs new file mode 100644 index 000000000..11cc49aef --- /dev/null +++ b/tests/rust/box.skip_cpp.rs @@ -0,0 +1,16 @@ +#[repr(C)] +pub struct MyStruct { + number: Box, +} + +pub struct NotReprC { + inner: T, +} + +pub type Foo = NotReprC>; + +#[no_mangle] +pub extern "C" fn root(a: &Foo, with_box: &MyStruct) {} + +#[no_mangle] +pub extern "C" fn delete(x: Box) {} From fa2da63c302d443321e27458c6152864787f7a0d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 29 Sep 2020 13:31:47 +0200 Subject: [PATCH 10/10] test: Ensure `Option>` reduces to `*T`. --- tests/rust/box.skip_cpp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rust/box.skip_cpp.rs b/tests/rust/box.skip_cpp.rs index 11cc49aef..a2e95d4ff 100644 --- a/tests/rust/box.skip_cpp.rs +++ b/tests/rust/box.skip_cpp.rs @@ -13,4 +13,4 @@ pub type Foo = NotReprC>; pub extern "C" fn root(a: &Foo, with_box: &MyStruct) {} #[no_mangle] -pub extern "C" fn delete(x: Box) {} +pub extern "C" fn delete(x: Option>) {}