diff options
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r-- | src/codegen/mod.rs | 74 |
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(); |