summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
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();