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 5, 2022
1 parent 73ce4bc commit 60c09cf
Show file tree
Hide file tree
Showing 11 changed files with 178 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;
2 changes: 1 addition & 1 deletion bindgen/Cargo.toml
Expand Up @@ -45,7 +45,7 @@ lazycell = "1"
lazy_static = "1"
peeking_take_while = "0.1.2"
quote = { version = "1", default-features = false }
syn = { version = "1.0.99", features = ["full", "extra-traits"]}
syn = { version = "1.0.99", features = ["full", "extra-traits", "visit-mut"]}
regex = { version = "1.5", default-features = false , features = ["std", "unicode"] }
which = { version = "4.2.1", optional = true, default-features = false }
shlex = "1"
Expand Down
7 changes: 6 additions & 1 deletion bindgen/codegen/postprocessing/merge_extern_blocks.rs
@@ -1,6 +1,11 @@
use syn::{Item, ItemForeignMod};

pub(super) fn merge_extern_blocks(items: &mut Vec<Item>) {
use crate::BindgenOptions;

pub(super) fn merge_extern_blocks(
items: &mut Vec<Item>,
_options: &BindgenOptions,
) {
// Keep all the extern blocks in a different `Vec` for faster search.
let mut foreign_mods = Vec::<ItemForeignMod>::new();

Expand Down
18 changes: 13 additions & 5 deletions bindgen/codegen/postprocessing/mod.rs
Expand Up @@ -5,14 +5,16 @@ use syn::Item;
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 Vec<Item>),
run: fn(&mut Vec<Item>, &BindgenOptions),
}

// TODO: This can be a const fn when mutable references are allowed in const
Expand All @@ -21,13 +23,19 @@ macro_rules! pass {
($pass:ident) => {
PostProcessingPass {
should_run: |options| options.$pass,
run: |items| $pass(items),
run: |items, options| $pass(items, options),
}
};
}

const PASSES: &[PostProcessingPass] =
&[pass!(merge_extern_blocks), pass!(sort_semantically)];
const PASSES: &[PostProcessingPass] = &[
pass!(merge_extern_blocks),
pass!(sort_semantically),
PostProcessingPass {
should_run: |options| !options.remove_alias.is_empty(),
run: |items, options| remove_alias(items, options),
},
];

pub(crate) fn postprocessing(
items: Vec<TokenStream>,
Expand Down Expand Up @@ -56,7 +64,7 @@ pub(crate) fn postprocessing(

for pass in PASSES {
if (pass.should_run)(options) {
(pass.run)(&mut items);
(pass.run)(&mut items, options);
}
}

Expand Down
53 changes: 53 additions & 0 deletions bindgen/codegen/postprocessing/remove_alias.rs
@@ -0,0 +1,53 @@
use syn::visit_mut::{visit_type_mut, VisitMut};
use syn::{Item, Type};

use crate::BindgenOptions;

pub(super) fn remove_alias(items: &mut Vec<Item>, options: &BindgenOptions) {
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)
}
}
4 changes: 3 additions & 1 deletion bindgen/codegen/postprocessing/sort_semantically.rs
@@ -1,6 +1,8 @@
use syn::Item;

pub(super) fn sort_semantically(items: &mut [Item]) {
use crate::BindgenOptions;

pub(super) fn sort_semantically(items: &mut [Item], _options: &BindgenOptions) {
items.sort_by_key(|item| match item {
Item::Type(_) => 0,
Item::Struct(_) => 1,
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 60c09cf

Please sign in to comment.