Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to remove type aliases #2295

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions bindgen-cli/options.rs
Expand Up @@ -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 <regex>.")
.value_name("regex")
.multiple_occurrences(true)
.number_of_values(1),
Arg::new("V")
.long("version")
.help("Prints the version, and exits"),
Expand Down Expand Up @@ -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))
}
60 changes: 60 additions & 0 deletions bindgen-tests/tests/expectations/tests/remove_alias.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions 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<typename T>
using integer = T;
8 changes: 7 additions & 1 deletion bindgen/codegen/postprocessing/merge_extern_blocks.rs
Expand Up @@ -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)
}

Expand Down
20 changes: 14 additions & 6 deletions bindgen/codegen/postprocessing/mod.rs
Expand Up @@ -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<TokenStream>,
Expand All @@ -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);
}
}

Expand Down
55 changes: 55 additions & 0 deletions 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<Type>,
}

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)
}
}
8 changes: 7 additions & 1 deletion bindgen/codegen/postprocessing/sort_semantically.rs
Expand Up @@ -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)
}

Expand Down
13 changes: 13 additions & 0 deletions bindgen/lib.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<T: Into<String>>(mut self, arg: T) -> Self {
self.options.remove_alias.insert(arg.into());
self
}
}

/// Configuration options for generated bindings.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -2261,6 +2273,7 @@ impl Default for BindgenOptions {
vtable_generation: false,
sort_semantically: false,
merge_extern_blocks: false,
remove_alias: Default::default(),
}
}
}
Expand Down