diff options
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | libbindgen/build.rs | 39 | ||||
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 7 | ||||
-rw-r--r-- | libbindgen/src/lib.rs | 10 | ||||
-rw-r--r-- | libbindgen/tests/tests.rs | 58 | ||||
-rw-r--r-- | src/options.rs | 7 |
6 files changed, 75 insertions, 47 deletions
diff --git a/.travis.yml b/.travis.yml index 48f0b4b1..9c7c1155 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ os: rust: - stable - - nightly env: - LLVM_VERSION=3.8 BINDGEN_FEATURES=llvm_stable diff --git a/libbindgen/build.rs b/libbindgen/build.rs index b9cf3e60..228a7f22 100644 --- a/libbindgen/build.rs +++ b/libbindgen/build.rs @@ -1,10 +1,9 @@ mod codegen { extern crate quasi_codegen; use std::path::Path; - use std::env; pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); + let out_dir = Path::new(env!("OUT_DIR")); let src = Path::new("src/codegen/mod.rs"); let dst = Path::new(&out_dir).join("codegen.rs"); @@ -14,6 +13,42 @@ mod codegen { } } +mod testgen { + use std::char; + use std::ffi::OsStr; + use std::fs::{self, File}; + use std::io::Write; + use std::path::Path; + + pub fn main() { + let out_dir = Path::new(env!("OUT_DIR")); + let mut dst = File::create(Path::new(&out_dir).join("tests.rs")).unwrap(); + + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let headers_dir = manifest_dir.join("tests").join("headers"); + + let entries = fs::read_dir(headers_dir) + .expect("Couldn't read headers dir") + .map(|result| result.expect("Couldn't read header file")); + + for entry in entries { + match entry.path().extension().and_then(OsStr::to_str) { + Some("h") | Some("hpp") => { + let func = entry.file_name().to_str().unwrap() + .replace(|c| !char::is_alphanumeric(c), "_") + .replace("__", "_") + .to_lowercase(); + let _ = writeln!(dst, "test_header!(header_{}, {:?});", + func, entry.path()); + } + _ => {} + } + } + let _ = dst.flush(); + } +} + fn main() { codegen::main(); + testgen::main(); } diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 65bc28d5..99ec56f4 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -1908,6 +1908,13 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> { let whitelisted_items: ItemSet = context.whitelisted_items().collect(); + if context.options().emit_ir { + for &id in whitelisted_items.iter() { + let item = context.resolve_item(id); + println!("ir: {:?} = {:#?}", id, item); + } + } + for &id in whitelisted_items.iter() { let item = context.resolve_item(id); diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs index d0ca7b03..e4923b77 100644 --- a/libbindgen/src/lib.rs +++ b/libbindgen/src/lib.rs @@ -225,6 +225,12 @@ impl Builder { self } + /// Emit IR. + pub fn emit_ir(mut self) -> Builder { + self.options.emit_ir = true; + self + } + /// Enable C++ namespaces. pub fn enable_cxx_namespaces(mut self) -> Builder { self.options.enable_cxx_namespaces = true; @@ -314,6 +320,9 @@ pub struct BindgenOptions { /// True if we should dump the Clang AST for debugging purposes. pub emit_ast: bool, + /// True if we should dump our internal IR for debugging purposes. + pub emit_ir: bool, + /// True if we should ignore functions and only generate bindings for /// structures, types, and methods. pub ignore_functions: bool, @@ -380,6 +389,7 @@ impl Default for BindgenOptions { builtins: false, links: vec![], emit_ast: false, + emit_ir: false, ignore_functions: false, ignore_methods: false, derive_debug: true, diff --git a/libbindgen/tests/tests.rs b/libbindgen/tests/tests.rs index c9826260..c0786406 100644 --- a/libbindgen/tests/tests.rs +++ b/libbindgen/tests/tests.rs @@ -6,10 +6,9 @@ extern crate libbindgen; extern crate log; extern crate shlex; -use std::env; use std::fs; use std::io::{BufRead, BufReader, Error, ErrorKind, Read}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; #[path="../../src/options.rs"] mod options; @@ -93,46 +92,17 @@ fn create_bindgen_builder(header: &PathBuf) builder_from_flags(args).map(|(builder, _)| builder.no_unstable_rust()) } -#[test] -fn run_bindgen_tests() { - log::set_logger(|max_log_level| { - use env_logger::Logger; - let env_logger = Logger::new(); - max_log_level.set(env_logger.filter()); - Box::new(env_logger) - }) - .expect("Failed to set logger."); - - let manifest_env = env::var("CARGO_MANIFEST_DIR") - .expect("CARGO_MANIFEST_DIR not set!"); - let manifest_dir = Path::new(&manifest_env); - let headers_dir = manifest_dir.join("tests").join("headers"); - - let entries = fs::read_dir(&headers_dir) - .expect("Couldn't read headers dir") - .map(|result| result.expect("Couldn't read header file")); - - let headers: Vec<_> = entries.filter_map(|entry| { - match entry.path().extension().and_then(|s| s.to_str()) { - Some("h") | Some("hpp") => Some(entry.path()), - _ => None, - } - }) - .collect(); - - let failures: Vec<_> = headers.iter() - .filter_map(|header| { - create_bindgen_builder(header) - .and_then(|builder| compare_generated_header(header, builder)) - .err() - }) - .collect(); - - let num_failures = failures.len(); - - if num_failures > 0 { - panic!("{} test{} failed!", - num_failures, - if num_failures > 1 {"s"} else {""}); - } +macro_rules! test_header { + ($function:ident, $header:expr) => ( + #[test] + fn $function() { + let header = PathBuf::from($header); + let _ = create_bindgen_builder(&header) + .and_then(|builder| compare_generated_header(&header, builder)) + .map_err(|err| panic!(format!("{}", err)) ); + } + ) } + +// This file is generated by build.rs +include!(concat!(env!("OUT_DIR"), "/tests.rs")); diff --git a/src/options.rs b/src/options.rs index c3c6a1f2..2ea74a27 100644 --- a/src/options.rs +++ b/src/options.rs @@ -52,6 +52,9 @@ pub fn builder_from_flags<I>(args: I) Arg::with_name("emit-clang-ast") .long("emit-clang-ast") .help("Output the Clang AST for debugging purposes."), + Arg::with_name("emit-ir") + .long("emit-ir") + .help("Output our internal IR for debugging purposes."), Arg::with_name("enable-cxx-namespaces") .long("enable-cxx-namespaces") .help("Enable support for C++ namespaces."), @@ -183,6 +186,10 @@ pub fn builder_from_flags<I>(args: I) builder = builder.emit_clang_ast(); } + if matches.is_present("emit-ir") { + builder = builder.emit_ir(); + } + if matches.is_present("enable-cxx-namespaces") { builder = builder.enable_cxx_namespaces(); } |