Skip to content

Commit

Permalink
add option to remove type aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdrz committed Oct 10, 2022
1 parent d241e95 commit 9281fb2
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 8 deletions.
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))
}
51 changes: 51 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.

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

14 changes: 14 additions & 0 deletions 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();
4 changes: 4 additions & 0 deletions bindgen-tests/tests/headers/remove_template_alias.hpp
@@ -0,0 +1,4 @@
// bindgen-flags: --remove-alias "Wrapped"

template<typename T>
using Wrapped = 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

0 comments on commit 9281fb2

Please sign in to comment.