summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-06-21 05:03:08 -0700
committerGitHub <noreply@github.com>2017-06-21 05:03:08 -0700
commit480c2d197199e7b1f824a01cc63acd33d81f6622 (patch)
treea244ca35506dc52f8a965a797dedeaa5715a5e82 /src/codegen/mod.rs
parent232a21ebc4a4ddc2468aed8e54d165c613037038 (diff)
parent814d28e0f256a24865f633b5992ced6f035d6f4c (diff)
Auto merge of #741 - tmfink:feature-699-constified-enum-module, r=emilio
Feature 699 constified enum module This is a work in progress for issue #699 that adds the `--constified-enum-module` option to bindgen. @emilio, could you give me some guidance on fixing the uses of the enum variant types? In the example below, `foo` should be replaced with `foo::Type`. I'm not sure of the proper way to rename `Item`s after the structures have been defined. My initial thought was to redefine the `CodeGenerator` trait to take a mutable reference to `item`, but that will not work because of the borrow checker. Thoughts? Todo: - [x] put constified enum variants in a `mod` - [x] ensure references to constified enum `foo` are changed to `foo::Type` - [x] handle `typedef` enums ----- Given the input header `tests/headers/constify-module-enums.h`: ~~~c // bindgen-flags: --constified-enum-module foo enum foo { THIS, SHOULD_BE, A_CONSTANT, }; struct bar { enum foo this_should_work; }; ~~~ `$ cargo run -- tests/headers/constify-module-enums.h --constified-enum-module foo --no-layout-tests` will output: ~~~rust /* automatically generated by rust-bindgen */ pub mod foo { pub type Type = ::std::os::raw::c_uint; pub const THIS: Type = 0; pub const SHOULD_BE: Type = 1; pub const A_CONSTANT: Type = 2; } #[repr(C)] #[derive(Debug, Copy)] pub struct bar { pub this_should_work: foo, } impl Clone for bar { fn clone(&self) -> Self { *self } } ~~~
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r--src/codegen/mod.rs74
1 files changed, 67 insertions, 7 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 3aff1b68..d926f02b 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -36,9 +36,12 @@ use std::mem;
use std::ops;
use syntax::abi;
use syntax::ast;
-use syntax::codemap::{Span, respan};
+use syntax::codemap::{DUMMY_SP, Span, respan};
use syntax::ptr::P;
+// Name of type defined in constified enum module
+pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type";
+
fn root_import_depth(ctx: &BindgenContext, item: &Item) -> usize {
if !ctx.options().enable_cxx_namespaces {
return 0;
@@ -244,7 +247,6 @@ impl ForeignModBuilder {
}
fn build(self, ctx: &BindgenContext) -> P<ast::Item> {
- use syntax::codemap::DUMMY_SP;
P(ast::Item {
ident: ctx.rust_ident(""),
id: ast::DUMMY_NODE_ID,
@@ -2049,6 +2051,10 @@ enum EnumBuilder<'a> {
aster: P<ast::Item>,
},
Consts { aster: P<ast::Item> },
+ ModuleConsts {
+ module_name: &'a str,
+ module_items: Vec<P<ast::Item>>,
+ },
}
impl<'a> EnumBuilder<'a> {
@@ -2058,7 +2064,8 @@ impl<'a> EnumBuilder<'a> {
name: &'a str,
repr: P<ast::Ty>,
bitfield_like: bool,
- constify: bool)
+ constify: bool,
+ constify_module: bool)
-> Self {
if bitfield_like {
EnumBuilder::Bitfield {
@@ -2070,8 +2077,20 @@ impl<'a> EnumBuilder<'a> {
.build(),
}
} else if constify {
- EnumBuilder::Consts {
- aster: aster.type_(name).build_ty(repr),
+ if constify_module {
+ let type_definition = aster::item::ItemBuilder::new()
+ .pub_()
+ .type_(CONSTIFIED_ENUM_MODULE_REPR_NAME)
+ .build_ty(repr);
+
+ EnumBuilder::ModuleConsts {
+ module_name: name,
+ module_items: vec![type_definition],
+ }
+ } else {
+ EnumBuilder::Consts {
+ aster: aster.type_(name).build_ty(repr),
+ }
}
} else {
EnumBuilder::Rust(aster.enum_(name))
@@ -2143,6 +2162,27 @@ impl<'a> EnumBuilder<'a> {
result.push(constant);
self
}
+ EnumBuilder::ModuleConsts { module_name, module_items, .. } => {
+ // Variant type
+ let inside_module_type =
+ aster::AstBuilder::new().ty().id(CONSTIFIED_ENUM_MODULE_REPR_NAME);
+
+ let constant = aster::AstBuilder::new()
+ .item()
+ .pub_()
+ .const_(&*variant_name)
+ .expr()
+ .build(expr)
+ .build(inside_module_type.clone());
+
+ let mut module_items = module_items.clone();
+ module_items.push(constant);
+
+ EnumBuilder::ModuleConsts {
+ module_name,
+ module_items,
+ }
+ }
}
}
@@ -2208,6 +2248,22 @@ impl<'a> EnumBuilder<'a> {
aster
}
EnumBuilder::Consts { aster, .. } => aster,
+ EnumBuilder::ModuleConsts { module_items, module_name, .. } => {
+ // Create module item with type and variant definitions
+ let module_item = P(ast::Item {
+ ident: ast::Ident::from_str(module_name),
+ attrs: vec![],
+ id: ast::DUMMY_NODE_ID,
+ node: ast::ItemKind::Mod(ast::Mod {
+ inner: DUMMY_SP,
+ items: module_items,
+ }),
+ vis: ast::Visibility::Public,
+ span: DUMMY_SP,
+ });
+
+ module_item
+ }
}
}
}
@@ -2273,7 +2329,10 @@ impl CodeGenerator for Enum {
.any(|v| ctx.options().bitfield_enums.matches(&v.name())))
};
- let is_constified_enum = {
+ let is_constified_enum_module = self.is_constified_enum_module(ctx, item);
+
+ let is_constified_enum = {
+ is_constified_enum_module ||
ctx.options().constified_enums.matches(&name) ||
(enum_ty.name().is_none() &&
self.variants()
@@ -2353,7 +2412,8 @@ impl CodeGenerator for Enum {
&name,
repr,
is_bitfield,
- is_constified_enum);
+ is_constified_enum,
+ is_constified_enum_module);
// A map where we keep a value -> variant relation.
let mut seen_values = HashMap::<_, String>::new();