From 9281fb2553c55d7c96b1237ac422e950e72d9b07 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 4 Oct 2022 14:47:53 -0500 Subject: [PATCH 1/2] add option to remove type aliases --- bindgen-cli/options.rs | 12 ++++ .../tests/expectations/tests/remove_alias.rs | 51 +++++++++++++++++ .../tests/remove_template_alias.rs | 8 +++ bindgen-tests/tests/headers/remove_alias.h | 14 +++++ .../tests/headers/remove_template_alias.hpp | 4 ++ .../postprocessing/merge_extern_blocks.rs | 8 ++- bindgen/codegen/postprocessing/mod.rs | 20 +++++-- .../codegen/postprocessing/remove_alias.rs | 55 +++++++++++++++++++ .../postprocessing/sort_semantically.rs | 8 ++- bindgen/lib.rs | 13 +++++ 10 files changed, 185 insertions(+), 8 deletions(-) create mode 100644 bindgen-tests/tests/expectations/tests/remove_alias.rs create mode 100644 bindgen-tests/tests/expectations/tests/remove_template_alias.rs create mode 100644 bindgen-tests/tests/headers/remove_alias.h create mode 100644 bindgen-tests/tests/headers/remove_template_alias.hpp create mode 100644 bindgen/codegen/postprocessing/remove_alias.rs diff --git a/bindgen-cli/options.rs b/bindgen-cli/options.rs index 5c3960e92b..3e4b3f224c 100644 --- a/bindgen-cli/options.rs +++ b/bindgen-cli/options.rs @@ -568,6 +568,12 @@ where Arg::new("merge-extern-blocks") .long("merge-extern-blocks") .help("Deduplicates extern blocks."), + Arg::new("remove-alias") + .long("remove-alias") + .help("Remove type aliases matching .") + .value_name("regex") + .multiple_occurrences(true) + .number_of_values(1), Arg::new("V") .long("version") .help("Prints the version, and exits"), @@ -1088,5 +1094,11 @@ where builder = builder.merge_extern_blocks(true); } + if let Some(remove_alias) = matches.values_of("remove-alias") { + for regex in remove_alias { + builder = builder.remove_alias(regex); + } + } + Ok((builder, output, verbose)) } diff --git a/bindgen-tests/tests/expectations/tests/remove_alias.rs b/bindgen-tests/tests/expectations/tests/remove_alias.rs new file mode 100644 index 0000000000..bae0fd07f3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/remove_alias.rs @@ -0,0 +1,51 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +pub type i32_ = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct int32_ { + pub inner: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_int32_() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(int32_)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(int32_)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).inner) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(int32_), + "::", + stringify!(inner) + ) + ); +} +extern "C" { + pub fn foo() -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn bar() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn baz() -> i32_; +} +extern "C" { + pub fn qux() -> int32_; +} diff --git a/bindgen-tests/tests/expectations/tests/remove_template_alias.rs b/bindgen-tests/tests/expectations/tests/remove_template_alias.rs new file mode 100644 index 0000000000..e06ffadab3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/remove_template_alias.rs @@ -0,0 +1,8 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +pub type Wrapped = T; diff --git a/bindgen-tests/tests/headers/remove_alias.h b/bindgen-tests/tests/headers/remove_alias.h new file mode 100644 index 0000000000..1b83396c25 --- /dev/null +++ b/bindgen-tests/tests/headers/remove_alias.h @@ -0,0 +1,14 @@ +// bindgen-flags: --remove-alias "int.*" + +typedef long long int64; +typedef int int32; +typedef int32 i32; + +struct int32_ { + int32 inner; +}; + +int64 foo(); +int32 bar(); +i32 baz(); +struct int32_ qux(); diff --git a/bindgen-tests/tests/headers/remove_template_alias.hpp b/bindgen-tests/tests/headers/remove_template_alias.hpp new file mode 100644 index 0000000000..a77021f726 --- /dev/null +++ b/bindgen-tests/tests/headers/remove_template_alias.hpp @@ -0,0 +1,4 @@ +// bindgen-flags: --remove-alias "Wrapped" + +template +using Wrapped = T; diff --git a/bindgen/codegen/postprocessing/merge_extern_blocks.rs b/bindgen/codegen/postprocessing/merge_extern_blocks.rs index 05e7e9ef39..8aea244028 100644 --- a/bindgen/codegen/postprocessing/merge_extern_blocks.rs +++ b/bindgen/codegen/postprocessing/merge_extern_blocks.rs @@ -3,7 +3,13 @@ use syn::{ Item, ItemForeignMod, ItemMod, }; -pub(super) fn merge_extern_blocks(item_mod: &mut ItemMod) { +use crate::BindgenOptions; + +#[inline] +pub(super) fn merge_extern_blocks( + item_mod: &mut ItemMod, + _options: &BindgenOptions, +) { Visitor.visit_item_mod_mut(item_mod) } diff --git a/bindgen/codegen/postprocessing/mod.rs b/bindgen/codegen/postprocessing/mod.rs index 1d5a4983bd..0095e8ac96 100644 --- a/bindgen/codegen/postprocessing/mod.rs +++ b/bindgen/codegen/postprocessing/mod.rs @@ -5,29 +5,37 @@ use syn::{parse2, ItemMod}; use crate::BindgenOptions; mod merge_extern_blocks; +mod remove_alias; mod sort_semantically; use merge_extern_blocks::merge_extern_blocks; +use remove_alias::remove_alias; use sort_semantically::sort_semantically; struct PostProcessingPass { should_run: fn(&BindgenOptions) -> bool, - run: fn(&mut ItemMod), + run: fn(&mut ItemMod, &BindgenOptions), } // TODO: This can be a const fn when mutable references are allowed in const // context. macro_rules! pass { ($pass:ident) => { + pass!($pass, |options| options.$pass) + }; + ($pass:ident, $should_run:expr) => { PostProcessingPass { - should_run: |options| options.$pass, - run: |item_mod| $pass(item_mod), + should_run: $should_run, + run: |item_mod, options| $pass(item_mod, options), } }; } -const PASSES: &[PostProcessingPass] = - &[pass!(merge_extern_blocks), pass!(sort_semantically)]; +const PASSES: &[PostProcessingPass] = &[ + pass!(merge_extern_blocks), + pass!(sort_semantically), + pass!(remove_alias, |options| !options.remove_alias.is_empty()), +]; pub(crate) fn postprocessing( items: Vec, @@ -51,7 +59,7 @@ pub(crate) fn postprocessing( for pass in PASSES { if (pass.should_run)(options) { - (pass.run)(&mut item_mod); + (pass.run)(&mut item_mod, options); } } diff --git a/bindgen/codegen/postprocessing/remove_alias.rs b/bindgen/codegen/postprocessing/remove_alias.rs new file mode 100644 index 0000000000..6b1e26a0c7 --- /dev/null +++ b/bindgen/codegen/postprocessing/remove_alias.rs @@ -0,0 +1,55 @@ +use syn::visit_mut::{visit_type_mut, VisitMut}; +use syn::{Item, ItemMod, Type}; + +use crate::BindgenOptions; + +pub(super) fn remove_alias(item_mod: &mut ItemMod, options: &BindgenOptions) { + if let Some((_, items)) = item_mod.content.as_mut() { + let visitors: Vec<_> = items + .iter() + .enumerate() + .rev() + .filter_map(|(index, item)| { + if let Item::Type(alias_item) = item { + if alias_item.generics.params.is_empty() { + let ident = alias_item.ident.to_string(); + if options.remove_alias.matches(&ident) { + return Some(( + index, + Visitor { + ident, + ty: alias_item.ty.clone(), + }, + )); + } + } + } + None + }) + .collect(); + + for (index, mut visitor) in visitors { + items.remove(index); + for item in items.iter_mut() { + visitor.visit_item_mut(item); + } + } + } +} + +struct Visitor { + ident: String, + ty: Box, +} + +impl VisitMut for Visitor { + fn visit_type_mut(&mut self, ty: &mut Type) { + if let Type::Path(type_path) = ty { + if type_path.path.is_ident(&self.ident) { + *ty = self.ty.as_ref().clone(); + } + } + + visit_type_mut::<_>(self, ty) + } +} diff --git a/bindgen/codegen/postprocessing/sort_semantically.rs b/bindgen/codegen/postprocessing/sort_semantically.rs index 4f23ab73a3..0603b88b03 100644 --- a/bindgen/codegen/postprocessing/sort_semantically.rs +++ b/bindgen/codegen/postprocessing/sort_semantically.rs @@ -3,7 +3,13 @@ use syn::{ Item, ItemMod, }; -pub(super) fn sort_semantically(item_mod: &mut ItemMod) { +use crate::BindgenOptions; + +#[inline] +pub(super) fn sort_semantically( + item_mod: &mut ItemMod, + _options: &BindgenOptions, +) { Visitor.visit_item_mod_mut(item_mod) } diff --git a/bindgen/lib.rs b/bindgen/lib.rs index 6e6fa225d6..878a6935b6 100644 --- a/bindgen/lib.rs +++ b/bindgen/lib.rs @@ -358,6 +358,7 @@ impl Builder { (&self.options.no_default_types, "--no-default"), (&self.options.no_hash_types, "--no-hash"), (&self.options.must_use_types, "--must-use-type"), + (&self.options.remove_alias, "--remove-alias"), ]; for (set, flag) in regex_sets { @@ -1770,6 +1771,13 @@ impl Builder { self.options.c_naming = doit; self } + + /// Remove a type alias that matches the provided argument. Regular + /// expressions are supported. + pub fn remove_alias>(mut self, arg: T) -> Self { + self.options.remove_alias.insert(arg.into()); + self + } } /// Configuration options for generated bindings. @@ -2105,6 +2113,9 @@ struct BindgenOptions { /// Deduplicate `extern` blocks. merge_extern_blocks: bool, + + /// The set of type aliases that should be removed. + remove_alias: RegexSet, } /// TODO(emilio): This is sort of a lie (see the error message that results from @@ -2142,6 +2153,7 @@ impl BindgenOptions { &mut self.no_default_types, &mut self.no_hash_types, &mut self.must_use_types, + &mut self.remove_alias, ]; let record_matches = self.record_matches; for regex_set in &mut regex_sets { @@ -2261,6 +2273,7 @@ impl Default for BindgenOptions { vtable_generation: false, sort_semantically: false, merge_extern_blocks: false, + remove_alias: Default::default(), } } } From e11637acd40b735a92d566142c9c5aa9979d1bec Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Wed, 5 Oct 2022 14:39:39 -0500 Subject: [PATCH 2/2] merge tests --- .../tests/expectations/tests/remove_alias.rs | 17 +++++++++++++---- .../tests/remove_template_alias.rs | 8 -------- bindgen-tests/tests/headers/remove_alias.h | 14 -------------- bindgen-tests/tests/headers/remove_alias.hpp | 18 ++++++++++++++++++ .../tests/headers/remove_template_alias.hpp | 4 ---- 5 files changed, 31 insertions(+), 30 deletions(-) delete mode 100644 bindgen-tests/tests/expectations/tests/remove_template_alias.rs delete mode 100644 bindgen-tests/tests/headers/remove_alias.h create mode 100644 bindgen-tests/tests/headers/remove_alias.hpp delete mode 100644 bindgen-tests/tests/headers/remove_template_alias.hpp diff --git a/bindgen-tests/tests/expectations/tests/remove_alias.rs b/bindgen-tests/tests/expectations/tests/remove_alias.rs index bae0fd07f3..37678ac594 100644 --- a/bindgen-tests/tests/expectations/tests/remove_alias.rs +++ b/bindgen-tests/tests/expectations/tests/remove_alias.rs @@ -38,14 +38,23 @@ fn bindgen_test_layout_int32_() { ); } extern "C" { - pub fn foo() -> ::std::os::raw::c_longlong; + #[link_name = "\u{1}_Z13returns_int64v"] + pub fn returns_int64() -> ::std::os::raw::c_longlong; } extern "C" { - pub fn bar() -> ::std::os::raw::c_int; + #[link_name = "\u{1}_Z13returns_int32v"] + pub fn returns_int32() -> ::std::os::raw::c_int; } extern "C" { - pub fn baz() -> i32_; + #[link_name = "\u{1}_Z11returns_i32v"] + pub fn returns_i32() -> i32_; } extern "C" { - pub fn qux() -> int32_; + #[link_name = "\u{1}_Z14returns_int32_v"] + pub fn returns_int32_() -> int32_; } +extern "C" { + #[link_name = "\u{1}_Z17returns_int32_ptrv"] + pub fn returns_int32_ptr() -> *mut ::std::os::raw::c_int; +} +pub type integer = T; diff --git a/bindgen-tests/tests/expectations/tests/remove_template_alias.rs b/bindgen-tests/tests/expectations/tests/remove_template_alias.rs deleted file mode 100644 index e06ffadab3..0000000000 --- a/bindgen-tests/tests/expectations/tests/remove_template_alias.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub type Wrapped = T; diff --git a/bindgen-tests/tests/headers/remove_alias.h b/bindgen-tests/tests/headers/remove_alias.h deleted file mode 100644 index 1b83396c25..0000000000 --- a/bindgen-tests/tests/headers/remove_alias.h +++ /dev/null @@ -1,14 +0,0 @@ -// bindgen-flags: --remove-alias "int.*" - -typedef long long int64; -typedef int int32; -typedef int32 i32; - -struct int32_ { - int32 inner; -}; - -int64 foo(); -int32 bar(); -i32 baz(); -struct int32_ qux(); diff --git a/bindgen-tests/tests/headers/remove_alias.hpp b/bindgen-tests/tests/headers/remove_alias.hpp new file mode 100644 index 0000000000..58f97f3145 --- /dev/null +++ b/bindgen-tests/tests/headers/remove_alias.hpp @@ -0,0 +1,18 @@ +// bindgen-flags: --remove-alias "int.*" + +typedef long long int64; +typedef int int32; +typedef int32 i32; +struct int32_ { + int32 inner; +}; +typedef int32* int32_ptr; + +int64 returns_int64(); +int32 returns_int32(); +i32 returns_i32(); +struct int32_ returns_int32_(); +int32_ptr returns_int32_ptr(); + +template +using integer = T; diff --git a/bindgen-tests/tests/headers/remove_template_alias.hpp b/bindgen-tests/tests/headers/remove_template_alias.hpp deleted file mode 100644 index a77021f726..0000000000 --- a/bindgen-tests/tests/headers/remove_template_alias.hpp +++ /dev/null @@ -1,4 +0,0 @@ -// bindgen-flags: --remove-alias "Wrapped" - -template -using Wrapped = T;