diff options
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/codegen/mod.rs | 38 | ||||
-rw-r--r-- | src/ir/item.rs | 33 | ||||
-rw-r--r-- | src/ir/traversal.rs | 29 | ||||
-rw-r--r-- | src/lib.rs | 95 | ||||
-rw-r--r-- | src/options.rs | 14 |
7 files changed, 120 insertions, 97 deletions
@@ -25,6 +25,7 @@ dependencies = [ name = "bindgen" version = "0.37.4" dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -47,6 +48,11 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "bitflags" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "cc" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -353,6 +359,7 @@ dependencies = [ "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" @@ -43,6 +43,7 @@ clap = "2" shlex = "0.1" [dependencies] +bitflags = "1.0.3" cexpr = "0.2" cfg-if = "0.1.0" # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 8c113f5a..35646c0d 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -14,6 +14,7 @@ use self::helpers::attributes; use self::struct_layout::StructLayoutTracker; use super::BindgenOptions; +use super::CodegenConfig; use ir::analysis::{HasVtable, Sizedness}; use ir::annotations::FieldAccessorKind; @@ -1842,7 +1843,11 @@ impl CodeGenerator for CompInfo { } let mut method_names = Default::default(); - if ctx.options().codegen_config.methods { + if ctx + .options() + .codegen_config + .contains(CodegenConfig::METHODS) + { for method in self.methods() { assert!(method.kind() != MethodKind::Constructor); method.codegen_method( @@ -1855,7 +1860,11 @@ impl CodeGenerator for CompInfo { } } - if ctx.options().codegen_config.constructors { + if ctx + .options() + .codegen_config + .contains(CodegenConfig::CONSTRUCTORS) + { for sig in self.constructors() { Method::new( MethodKind::Constructor, @@ -1872,7 +1881,11 @@ impl CodeGenerator for CompInfo { } } - if ctx.options().codegen_config.destructors { + if ctx + .options() + .codegen_config + .contains(CodegenConfig::DESTRUCTORS) + { if let Some((kind, destructor)) = self.destructor() { debug_assert!(kind.is_destructor()); Method::new(kind, destructor, false).codegen_method( @@ -1978,11 +1991,20 @@ impl MethodCodegen for Method { assert!({ let cc = &ctx.options().codegen_config; match self.kind() { - MethodKind::Constructor => cc.constructors, - MethodKind::Destructor => cc.destructors, - MethodKind::VirtualDestructor { .. } => cc.destructors, - MethodKind::Static | MethodKind::Normal | - MethodKind::Virtual { .. } => cc.methods, + MethodKind::Constructor => { + cc.contains(CodegenConfig::CONSTRUCTORS) + } + MethodKind::Destructor => { + cc.contains(CodegenConfig::DESTRUCTORS) + } + MethodKind::VirtualDestructor { .. } => { + cc.contains(CodegenConfig::DESTRUCTORS) + } + MethodKind::Static + | MethodKind::Normal + | MethodKind::Virtual { .. } => { + cc.contains(CodegenConfig::METHODS) + } } }); diff --git a/src/ir/item.rs b/src/ir/item.rs index 927322eb..67ba9947 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -13,6 +13,7 @@ use super::function::{Function, FunctionKind}; use super::item_kind::ItemKind; use super::layout::Opaque; use super::module::Module; +use super::super::CodegenConfig; use super::super::codegen::CONSTIFIED_ENUM_MODULE_REPR_NAME; use super::template::{AsTemplateParam, TemplateParameters}; use super::traversal::{EdgeKind, Trace, Tracer}; @@ -951,23 +952,23 @@ impl Item { let cc = &ctx.options().codegen_config; match *self.kind() { ItemKind::Module(..) => true, - ItemKind::Var(_) => cc.vars, - ItemKind::Type(_) => cc.types, - ItemKind::Function(ref f) => { - match f.kind() { - FunctionKind::Function => cc.functions, - FunctionKind::Method(MethodKind::Constructor) => { - cc.constructors - } - FunctionKind::Method(MethodKind::Destructor) | - FunctionKind::Method(MethodKind::VirtualDestructor { .. }) => { - cc.destructors - } - FunctionKind::Method(MethodKind::Static) | - FunctionKind::Method(MethodKind::Normal) | - FunctionKind::Method(MethodKind::Virtual { .. }) => cc.methods, + ItemKind::Var(_) => cc.contains(CodegenConfig::VARS), + ItemKind::Type(_) => cc.contains(CodegenConfig::TYPES), + ItemKind::Function(ref f) => match f.kind() { + FunctionKind::Function => cc.contains(CodegenConfig::FUNCTIONS), + FunctionKind::Method(MethodKind::Constructor) => { + cc.contains(CodegenConfig::CONSTRUCTORS) } - } + FunctionKind::Method(MethodKind::Destructor) + | FunctionKind::Method(MethodKind::VirtualDestructor { + .. + }) => cc.contains(CodegenConfig::DESTRUCTORS), + FunctionKind::Method(MethodKind::Static) + | FunctionKind::Method(MethodKind::Normal) + | FunctionKind::Method(MethodKind::Virtual { .. }) => { + cc.contains(CodegenConfig::METHODS) + } + }, } } } diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs index c37b0b5f..d69e7541 100644 --- a/src/ir/traversal.rs +++ b/src/ir/traversal.rs @@ -1,5 +1,6 @@ //! Traversal of the graph of IR items and types. +use super::super::CodegenConfig; use super::context::{BindgenContext, ItemId}; use super::item::ItemSet; use std::collections::{BTreeMap, VecDeque}; @@ -223,20 +224,20 @@ pub fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool { // We statically know the kind of item that non-generic edges can point // to, so we don't need to actually resolve the item and check // `Item::is_enabled_for_codegen`. - EdgeKind::TemplateParameterDefinition | - EdgeKind::TemplateArgument | - EdgeKind::TemplateDeclaration | - EdgeKind::BaseMember | - EdgeKind::Field | - EdgeKind::InnerType | - EdgeKind::FunctionReturn | - EdgeKind::FunctionParameter | - EdgeKind::VarType | - EdgeKind::TypeReference => cc.types, - EdgeKind::InnerVar => cc.vars, - EdgeKind::Method => cc.methods, - EdgeKind::Constructor => cc.constructors, - EdgeKind::Destructor => cc.destructors, + EdgeKind::TemplateParameterDefinition + | EdgeKind::TemplateArgument + | EdgeKind::TemplateDeclaration + | EdgeKind::BaseMember + | EdgeKind::Field + | EdgeKind::InnerType + | EdgeKind::FunctionReturn + | EdgeKind::FunctionParameter + | EdgeKind::VarType + | EdgeKind::TypeReference => cc.contains(CodegenConfig::TYPES), + EdgeKind::InnerVar => cc.contains(CodegenConfig::VARS), + EdgeKind::Method => cc.contains(CodegenConfig::METHODS), + EdgeKind::Constructor => cc.contains(CodegenConfig::CONSTRUCTORS), + EdgeKind::Destructor => cc.contains(CodegenConfig::DESTRUCTORS), } } @@ -16,6 +16,8 @@ // `quote!` nests quite deeply. #![recursion_limit="128"] +#[macro_use] +extern crate bitflags; extern crate cexpr; #[macro_use] #[allow(unused_extern_crates)] @@ -100,48 +102,21 @@ fn args_are_cpp(clang_args: &[String]) -> bool { .any(|w| w[0] == "-x=c++" || w[1] == "-x=c++" || w == &["-x", "c++"]); } -/// A type used to indicate which kind of items do we have to generate. -/// -/// TODO(emilio): Use `bitflags!` -#[derive(Debug, Clone)] -pub struct CodegenConfig { - /// Whether to generate functions. - pub functions: bool, - /// Whether to generate types. - pub types: bool, - /// Whether to generate constants. - pub vars: bool, - /// Whether to generate methods. - pub methods: bool, - /// Whether to generate constructors. - pub constructors: bool, - /// Whether to generate destructors. - pub destructors: bool, -} - -impl CodegenConfig { - /// Generate all kinds of items. - pub fn all() -> Self { - CodegenConfig { - functions: true, - types: true, - vars: true, - methods: true, - constructors: true, - destructors: true, - } - } - - /// Generate nothing. - pub fn nothing() -> Self { - CodegenConfig { - functions: false, - types: false, - vars: false, - methods: false, - constructors: false, - destructors: false, - } +bitflags! { + /// A type used to indicate which kind of items we have to generate. + pub struct CodegenConfig: u32 { + /// Whether to generate functions. + const FUNCTIONS = 0b1 << 0; + /// Whether to generate types. + const TYPES = 0b1 << 1; + /// Whether to generate constants. + const VARS = 0b1 << 2; + /// Whether to generate methods. + const METHODS = 0b1 << 3; + /// Whether to generate constructors + const CONSTRUCTORS = 0b1 << 4; + /// Whether to generate destructors. + const DESTRUCTORS = 0b1 << 5; } } @@ -393,7 +368,11 @@ impl Builder { output_vector.push("--disable-name-namespacing".into()); } - if !self.options.codegen_config.functions { + if !self + .options + .codegen_config + .contains(CodegenConfig::FUNCTIONS) + { output_vector.push("--ignore-functions".into()); } @@ -401,28 +380,40 @@ impl Builder { //Temporary placeholder for below 4 options let mut options: Vec<String> = Vec::new(); - if self.options.codegen_config.functions { + if self + .options + .codegen_config + .contains(CodegenConfig::FUNCTIONS) + { options.push("function".into()); } - if self.options.codegen_config.types { + if self.options.codegen_config.contains(CodegenConfig::TYPES) { options.push("types".into()); } - if self.options.codegen_config.vars { + if self.options.codegen_config.contains(CodegenConfig::VARS) { options.push("vars".into()); } - if self.options.codegen_config.methods { + if self.options.codegen_config.contains(CodegenConfig::METHODS) { options.push("methods".into()); } - if self.options.codegen_config.constructors { + if self + .options + .codegen_config + .contains(CodegenConfig::CONSTRUCTORS) + { options.push("constructors".into()); } - if self.options.codegen_config.destructors { + if self + .options + .codegen_config + .contains(CodegenConfig::DESTRUCTORS) + { options.push("destructors".into()); } output_vector.push(options.join(",")); - if !self.options.codegen_config.methods { + if !self.options.codegen_config.contains(CodegenConfig::METHODS) { output_vector.push("--ignore-methods".into()); } @@ -1070,13 +1061,13 @@ impl Builder { /// Ignore functions. pub fn ignore_functions(mut self) -> Builder { - self.options.codegen_config.functions = false; + self.options.codegen_config.remove(CodegenConfig::FUNCTIONS); self } /// Ignore methods. pub fn ignore_methods(mut self) -> Builder { - self.options.codegen_config.methods = false; + self.options.codegen_config.remove(CodegenConfig::METHODS); self } diff --git a/src/options.rs b/src/options.rs index c65a80fc..07195bfe 100644 --- a/src/options.rs +++ b/src/options.rs @@ -428,15 +428,15 @@ where } if let Some(what_to_generate) = matches.value_of("generate") { - let mut config = CodegenConfig::nothing(); + let mut config = CodegenConfig::empty(); for what in what_to_generate.split(",") { match what { - "functions" => config.functions = true, - "types" => config.types = true, - "vars" => config.vars = true, - "methods" => config.methods = true, - "constructors" => config.constructors = true, - "destructors" => config.destructors = true, + "functions" => config.insert(CodegenConfig::FUNCTIONS), + "types" => config.insert(CodegenConfig::TYPES), + "vars" => config.insert(CodegenConfig::VARS), + "methods" => config.insert(CodegenConfig::METHODS), + "constructors" => config.insert(CodegenConfig::CONSTRUCTORS), + "destructors" => config.insert(CodegenConfig::DESTRUCTORS), otherwise => { return Err(Error::new( ErrorKind::Other, |