Skip to content

Allow blocklisting anonymous enums #3067

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into #1025 and I'm assuming that the anonymous enum with no variants was just an example and nobody actually needs a typedef for an anonymous enum with no variants (which would be blocked by this PR, unless we specifically want to preserve existing behavior, since .all() in Rust returns true if there is nothing to iterate over).

I added some cases for the other possibilities and the typedef is still generated correctly for all the enum definitions that could be used in some way.
CC @ctaggart who reported #1025, just in case I'm missing something and they had an actual usecase for a typedef for an anonymous enum with no variants.

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

7 changes: 7 additions & 0 deletions bindgen-tests/tests/headers/blocklist-anon-enum.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// bindgen-flags: --blocklist-item 'SHOULD_BE_BLOCKED.*'

enum {
SHOULD_BE_BLOCKED_1,
SHOULD_BE_BLOCKED_2,
SHOULD_BE_BLOCKED_3
};
16 changes: 16 additions & 0 deletions bindgen-tests/tests/headers/issue-1025-unknown-enum-repr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,19 @@
template <typename> class a {
enum {};
};

template <typename> class b {
enum {
SOME_VARIANT
};
};

template <typename> class c {
enum my_enum {
MY_ENUM_SOME_VARIANT
};
};

template <typename> class d {
enum no_variant_enum {};
};
12 changes: 12 additions & 0 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3654,6 +3654,18 @@ impl CodeGenerator for Enum {
let layout = enum_ty.layout(ctx);
let variation = self.computed_enum_variation(ctx, item);

// blocklist anonymous enums if all variants match a regex.
// Note: This will also block anonymous enums with no variants, but
// adding a typedef for such an enum should be useless anyway.
if enum_ty.name().is_none() &&
self.variants()
.iter()
.all(|v| ctx.options().blocklisted_items.matches(v.name()))
{
debug!("Blocklisting anonymous enum.");
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this only block the enum if all variants, and not any are blocklisted? If not, can we document this behavior and why is it useful? thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior of using any variant matches for anonymous enums is not new, and already works when allowlisting anonymous enums, so there is a (probably small) risk that changing the way matching works could break users who are relying on the current behavior for allowlisting.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you can individually hide variants (via annotations or callbacks), right...

I'd expect allowlisting to work with any and blocklisting to work with all, if that makes sense... But let me know if you disagree, maybe my expectation is flawed somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think that's perfectly reasonable. I changed this PR to use all instead. This will also block all anonymous enums without variants (See my comment on test 1025 below).


let repr_translated;
let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) {
Some(repr)
Expand Down
6 changes: 5 additions & 1 deletion bindgen/ir/enum_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ impl Enum {
Ok(Enum::new(repr, variants))
}

fn is_matching_enum(
/// Checks if the enum matches any of the regular expressions in `enums`
///
/// For anonymous enums, returns true if any of the enum variants matches
/// any of the regular expressions in `enums`.
pub(crate) fn is_matching_enum(
&self,
ctx: &BindgenContext,
enums: &RegexSet,
Expand Down
Loading