summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--libbindgen/build.rs39
-rw-r--r--libbindgen/src/codegen/mod.rs7
-rw-r--r--libbindgen/src/lib.rs10
-rw-r--r--libbindgen/tests/tests.rs58
-rw-r--r--src/options.rs7
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();
}