Skip to content

Commit 4403741

Browse files
author
bors-servo
authored
Auto merge of #1328 - db48x:default-enum-variant, r=emilio
Add an option to set the default codegen style for all enums
2 parents cfd0fa5 + 393e779 commit 4403741

15 files changed

+194
-13
lines changed

src/codegen/mod.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use ir::var::Var;
4040
use quote;
4141
use proc_macro2::{self, Term, Span};
4242

43+
use std;
4344
use std::borrow::Cow;
4445
use std::cell::Cell;
4546
use std::collections::{HashSet, VecDeque};
@@ -2103,11 +2104,15 @@ impl MethodCodegen for Method {
21032104
}
21042105

21052106
/// A helper type that represents different enum variations.
2106-
#[derive(Copy, Clone)]
2107-
enum EnumVariation {
2107+
#[derive(Copy, Clone, PartialEq, Debug)]
2108+
pub enum EnumVariation {
2109+
/// The code for this enum will use a Rust enum
21082110
Rust,
2111+
/// The code for this enum will use a bitfield
21092112
Bitfield,
2113+
/// The code for this enum will use consts
21102114
Consts,
2115+
/// The code for this enum will use a module containing consts
21112116
ModuleConsts
21122117
}
21132118

@@ -2136,6 +2141,31 @@ impl EnumVariation {
21362141
}
21372142
}
21382143

2144+
impl Default for EnumVariation {
2145+
fn default() -> EnumVariation {
2146+
EnumVariation::Consts
2147+
}
2148+
}
2149+
2150+
impl std::str::FromStr for EnumVariation {
2151+
type Err = std::io::Error;
2152+
2153+
/// Create a `EnumVariation` from a string.
2154+
fn from_str(s: &str) -> Result<Self, Self::Err> {
2155+
match s {
2156+
"rust" => Ok(EnumVariation::Rust),
2157+
"bitfield" => Ok(EnumVariation::Bitfield),
2158+
"consts" => Ok(EnumVariation::Consts),
2159+
"moduleconsts" => Ok(EnumVariation::ModuleConsts),
2160+
_ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,
2161+
concat!("Got an invalid EnumVariation. Accepted values ",
2162+
"are 'rust', 'bitfield', 'consts', and ",
2163+
"'moduleconsts'."))),
2164+
}
2165+
}
2166+
}
2167+
2168+
21392169
/// A helper type to construct different enum variations.
21402170
enum EnumBuilder<'a> {
21412171
Rust {
@@ -2491,8 +2521,7 @@ impl CodeGenerator for Enum {
24912521
} else if self.is_rustified_enum(ctx, item) {
24922522
EnumVariation::Rust
24932523
} else {
2494-
// We generate consts by default
2495-
EnumVariation::Consts
2524+
ctx.options().default_enum_style
24962525
};
24972526

24982527
let mut attrs = vec![];

src/lib.rs

+20
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ use ir::context::{BindgenContext, ItemId};
8383
use ir::item::Item;
8484
use parse::{ClangItemParser, ParseError};
8585
use regex_set::RegexSet;
86+
pub use codegen::EnumVariation;
8687

8788
use std::borrow::Cow;
8889
use std::collections::HashMap;
@@ -203,6 +204,16 @@ impl Builder {
203204
output_vector.push("--rust-target".into());
204205
output_vector.push(self.options.rust_target.into());
205206

207+
if self.options.default_enum_style != Default::default() {
208+
output_vector.push("--default-enum-variant=".into());
209+
output_vector.push(match self.options.default_enum_style {
210+
codegen::EnumVariation::Rust => "rust",
211+
codegen::EnumVariation::Bitfield => "bitfield",
212+
codegen::EnumVariation::Consts => "consts",
213+
codegen::EnumVariation::ModuleConsts => "moduleconsts",
214+
}.into())
215+
}
216+
206217
self.options
207218
.bitfield_enums
208219
.get_items()
@@ -729,6 +740,11 @@ impl Builder {
729740
self.whitelist_var(arg)
730741
}
731742

743+
/// Set the default style of code to generate for enums
744+
pub fn default_enum_style(mut self, arg: codegen::EnumVariation) -> Builder {
745+
self.options.default_enum_style = arg;
746+
self
747+
}
732748

733749
/// Mark the given enum (or set of enums, if using a pattern) as being
734750
/// bitfield-like. Regular expressions are supported.
@@ -1240,6 +1256,9 @@ struct BindgenOptions {
12401256
/// Whitelisted variables. See docs for `whitelisted_types` for more.
12411257
whitelisted_vars: RegexSet,
12421258

1259+
/// The default style of code to generate for enums
1260+
default_enum_style: codegen::EnumVariation,
1261+
12431262
/// The enum patterns to mark an enum as bitfield.
12441263
bitfield_enums: RegexSet,
12451264

@@ -1458,6 +1477,7 @@ impl Default for BindgenOptions {
14581477
whitelisted_types: Default::default(),
14591478
whitelisted_functions: Default::default(),
14601479
whitelisted_vars: Default::default(),
1480+
default_enum_style: Default::default(),
14611481
bitfield_enums: Default::default(),
14621482
rustified_enums: Default::default(),
14631483
constified_enum_modules: Default::default(),

src/options.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder};
1+
use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder, EnumVariation};
22
use clap::{App, Arg};
33
use std::fs::File;
44
use std::io::{self, Error, ErrorKind, Write, stderr};
@@ -26,6 +26,13 @@ where
2626
Arg::with_name("header")
2727
.help("C or C++ header file")
2828
.required(true),
29+
Arg::with_name("default-enum-style")
30+
.long("default-enum-style")
31+
.help("The default style of code used to generate enums.")
32+
.value_name("variant")
33+
.default_value("consts")
34+
.possible_values(&["consts", "moduleconsts", "bitfield", "rust"])
35+
.multiple(false),
2936
Arg::with_name("bitfield-enum")
3037
.long("bitfield-enum")
3138
.help("Mark any enum whose name matches <regex> as a set of \
@@ -303,6 +310,10 @@ where
303310
builder = builder.rust_target(RustTarget::from_str(rust_target)?);
304311
}
305312

313+
if let Some(variant) = matches.value_of("default-enum-style") {
314+
builder = builder.default_enum_style(EnumVariation::from_str(variant)?)
315+
}
316+
306317
if let Some(bitfields) = matches.values_of("bitfield-enum") {
307318
for regex in bitfields {
308319
builder = builder.bitfield_enum(regex);

tests/expectations/tests/bitfield-32bit-overflow.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* automatically generated by rust-bindgen */
22

3-
43
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
54

6-
75
#[repr(C)]
86
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
97
pub struct __BindgenBitfieldUnit<Storage, Align>

tests/expectations/tests/bitfield_align.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* automatically generated by rust-bindgen */
22

3-
43
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
54

6-
75
#[repr(C)]
86
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
97
pub struct __BindgenBitfieldUnit<Storage, Align>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
impl Foo {
6+
pub const Bar: Foo = Foo(0);
7+
}
8+
impl Foo {
9+
pub const Qux: Foo = Foo(1);
10+
}
11+
impl ::std::ops::BitOr<Foo> for Foo {
12+
type Output = Self;
13+
#[inline]
14+
fn bitor(self, other: Self) -> Self {
15+
Foo(self.0 | other.0)
16+
}
17+
}
18+
impl ::std::ops::BitOrAssign for Foo {
19+
#[inline]
20+
fn bitor_assign(&mut self, rhs: Foo) {
21+
self.0 |= rhs.0;
22+
}
23+
}
24+
impl ::std::ops::BitAnd<Foo> for Foo {
25+
type Output = Self;
26+
#[inline]
27+
fn bitand(self, other: Self) -> Self {
28+
Foo(self.0 & other.0)
29+
}
30+
}
31+
impl ::std::ops::BitAndAssign for Foo {
32+
#[inline]
33+
fn bitand_assign(&mut self, rhs: Foo) {
34+
self.0 &= rhs.0;
35+
}
36+
}
37+
#[repr(C)]
38+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
39+
pub struct Foo(pub u32);
40+
pub mod Neg {
41+
pub type Type = i32;
42+
pub const MinusOne: Type = -1;
43+
pub const One: Type = 1;
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
pub const Foo_Bar: Foo = 0;
6+
pub const Foo_Qux: Foo = 1;
7+
pub type Foo = u32;
8+
pub mod Neg {
9+
pub type Type = i32;
10+
pub const MinusOne: Type = -1;
11+
pub const One: Type = 1;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
pub mod Foo {
6+
pub type Type = u32;
7+
pub const Bar: Type = 0;
8+
pub const Qux: Type = 1;
9+
}
10+
pub mod Neg {
11+
pub type Type = i32;
12+
pub const MinusOne: Type = -1;
13+
pub const One: Type = 1;
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
#[repr(u32)]
6+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
7+
pub enum Foo {
8+
Bar = 0,
9+
Qux = 1,
10+
}
11+
pub mod Neg {
12+
pub type Type = i32;
13+
pub const MinusOne: Type = -1;
14+
pub const One: Type = 1;
15+
}

tests/expectations/tests/issue-739-pointer-wide-bitfield.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* automatically generated by rust-bindgen */
22

3-
43
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
54

6-
75
#[repr(C)]
86
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
97
pub struct __BindgenBitfieldUnit<Storage, Align>

tests/expectations/tests/struct_with_bitfields.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* automatically generated by rust-bindgen */
22

3-
43
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
54

6-
75
#[repr(C)]
86
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
97
pub struct __BindgenBitfieldUnit<Storage, Align>

tests/headers/enum-default-bitfield.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// bindgen-flags: --default-enum-style=bitfield --constified-enum-module=Neg
2+
3+
enum Foo {
4+
Bar = 0,
5+
Qux
6+
};
7+
8+
enum Neg {
9+
MinusOne = -1,
10+
One = 1,
11+
};

tests/headers/enum-default-consts.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// bindgen-flags: --default-enum-style=consts --constified-enum-module=Neg
2+
3+
enum Foo {
4+
Bar = 0,
5+
Qux
6+
};
7+
8+
enum Neg {
9+
MinusOne = -1,
10+
One = 1,
11+
};

tests/headers/enum-default-module.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// bindgen-flags: --default-enum-style=moduleconsts --constified-enum-module=Neg
2+
3+
enum Foo {
4+
Bar = 0,
5+
Qux
6+
};
7+
8+
enum Neg {
9+
MinusOne = -1,
10+
One = 1,
11+
};

tests/headers/enum-default-rust.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// bindgen-flags: --default-enum-style=rust --constified-enum-module=Neg
2+
3+
enum Foo {
4+
Bar = 0,
5+
Qux
6+
};
7+
8+
enum Neg {
9+
MinusOne = -1,
10+
One = 1,
11+
};

0 commit comments

Comments
 (0)