From 1bc2750d80ef8af5445662afb5692018d1c95c1d Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 24 Oct 2016 14:13:13 -0700 Subject: [PATCH 1/2] Add `#![deny(missing_docs)]` This commit adds the `#![deny(missing_docs)]` pragma, which causes compilation to fail if a public type or function is missing a documentation comment. It also adds missing documentation comments for public types and functions that were missing them. --- src/bin/bindgen.rs | 3 ++ src/codegen/mod.rs | 0 src/lib.rs | 117 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 116 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/codegen/mod.rs diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index 183257c829..119776bdf5 100755 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -90,6 +90,9 @@ Options: // FIXME(emilio): Replace this with docopt if/when they fix their exponential // algorithm for argument parsing. +// +// FIXME(fitzgen): Switch from `BindgenOptions` to the non-deprecated `Builder`. +#[allow(deprecated)] fn parse_args_or_exit(args: Vec) -> (BindgenOptions, Box) { let mut options = BindgenOptions::default(); let mut dest_file = None; diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs old mode 100644 new mode 100755 diff --git a/src/lib.rs b/src/lib.rs index 4464db65d7..8f89b44714 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,22 @@ +//! Generate Rust bindings for C and C++ libraries. +//! +//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++ +//! functions and use types defined in the header. +//! +//! See the [Builder](./struct.Builder.html) struct for usage. + #![crate_name = "bindgen"] #![crate_type = "dylib"] #![cfg_attr(feature = "clippy", feature(plugin))] #![cfg_attr(feature = "clippy", plugin(clippy))] +#![deny(missing_docs)] + +// We internally use the deprecated BindgenOptions all over the place. Once we +// remove its `pub` declaration, we can un-deprecate it and remove this pragma. +#![allow(deprecated)] + // To avoid rather annoying warnings when matching with CXCursor_xxx as a // constant. #![allow(non_upper_case_globals)] @@ -45,107 +58,189 @@ use ir::item::{Item, ItemId}; use parse::{ClangItemParser, ParseError}; use regex_set::RegexSet; +/// Configure and generate Rust bindings for a C/C++ header. +/// +/// This is the main entry point to the library. +/// +/// ```ignore +/// use bindgen::builder; +/// +/// // Configure and generate bindings. +/// let bindings = try!(builder().header("path/to/input/header") +/// .whitelisted_type("SomeCoolClass") +/// .whitelisted_function("do_some_cool_thing") +/// .generate()); +/// +/// // Write the generated bindings to an output file. +/// try!(bindings.write_to_file("path/to/output.rs")); +/// ``` #[derive(Debug,Default)] pub struct Builder { options: BindgenOptions, } +/// Construct a new [`Builder`](./struct.Builder.html). pub fn builder() -> Builder { Default::default() } impl Builder { + /// Set the input C/C++ header. pub fn header>(self, header: T) -> Builder { self.clang_arg(header) } + /// Hide the given type from the generated bindings. pub fn hide_type>(mut self, arg: T) -> Builder { self.options.hidden_types.insert(arg.into()); self } + /// Treat the given type as opaque in the generated bindings. pub fn opaque_type>(mut self, arg: T) -> Builder { self.options.opaque_types.insert(arg.into()); self } + /// Whitelist the given type so that it (and all types that it transitively + /// refers to) appears in the generated bindings. pub fn whitelisted_type>(mut self, arg: T) -> Builder { self.options.whitelisted_types.insert(&arg); self } + /// Whitelist the given function so that it (and all types that it + /// transitively refers to) appears in the generated bindings. pub fn whitelisted_function>(mut self, arg: T) -> Builder { self.options.whitelisted_functions.insert(&arg); self } + /// Whitelist the given variable so that it (and all types that it + /// transitively refers to) appears in the generated bindings. pub fn whitelisted_var>(mut self, arg: T) -> Builder { self.options.whitelisted_vars.insert(&arg); self } + /// Add a string to prepend to the generated bindings. The string is passed + /// through without any modification. pub fn raw_line>(mut self, arg: T) -> Builder { self.options.raw_lines.push(arg.into()); self } + /// Add an argument to be passed straight through to clang. pub fn clang_arg>(mut self, arg: T) -> Builder { self.options.clang_args.push(arg.into()); self } + /// Make the generated bindings link the given shared library. pub fn link>(mut self, library: T) -> Builder { self.options.links.push((library.into(), LinkType::Default)); self } + /// Make the generated bindings link the given static library. pub fn link_static>(mut self, library: T) -> Builder { self.options.links.push((library.into(), LinkType::Static)); self } + /// Make the generated bindings link the given framework. pub fn link_framework>(mut self, library: T) -> Builder { self.options.links.push((library.into(), LinkType::Framework)); self } + /// Emit bindings for builtin definitions (for example `__builtin_va_list`) + /// in the generated Rust. pub fn emit_builtins(mut self) -> Builder { self.options.builtins = true; self } + /// Avoid generating any unstable Rust in the generated bindings. pub fn no_unstable_rust(mut self) -> Builder { self.options.unstable_rust = false; self } + /// Generate the Rust bindings using the options built up thus far. pub fn generate(self) -> Result { Bindings::generate(self.options, None) } } -/// Deprecated - use a `Builder` instead +/// Configuration options for generated bindings. +/// +/// Deprecated: use a `Builder` instead. #[derive(Debug)] +#[deprecated] pub struct BindgenOptions { + /// The set of types that have been blacklisted and should not appear + /// anywhere in the generated code. pub hidden_types: HashSet, + + /// The set of types that should be treated as opaque structures in the + /// generated code. pub opaque_types: HashSet, + + /// The set of types that we should have bindings for in the generated + /// code. + /// + /// This includes all types transitively reachable from any type in this + /// set. One might think of whitelisted types/vars/functions as GC roots, + /// and the generated Rust code as including everything that gets marked. pub whitelisted_types: RegexSet, + + /// Whitelisted functions. See docs for `whitelisted_types` for more. pub whitelisted_functions: RegexSet, + + /// Whitelisted variables. See docs for `whitelisted_types` for more. pub whitelisted_vars: RegexSet, + + /// Whether we should generate builtins or not. pub builtins: bool, + + /// The set of libraries we should link in the generated Rust code. pub links: Vec<(String, LinkType)>, + + /// True if we should dump the Clang AST for debugging purposes. pub emit_ast: bool, + + /// True if we should ignore functions and only generate bindings for + /// structures, types, and methods. pub ignore_functions: bool, + + /// True if we should avoid generating bindings for methods, and instead + /// just generate code for structures and types. pub ignore_methods: bool, + + /// True if we should emulate C++ namespaces with Rust modules in the + /// generated bindings. pub enable_cxx_namespaces: bool, + + /// True if we shold derive Debug trait implementations for C/C++ structures + /// and types. pub derive_debug: bool, - /// Generate or not only stable rust. + + /// True if we can use unstable Rust code in the bindings, false if we + /// cannot. pub unstable_rust: bool, - /// Wether to generate names that are **directly** under namespaces. + + /// True if we should generate constant names that are **directly** under + /// namespaces. pub namespaced_constants: bool, - /// Whether to use msvc mangling rules + + /// True if we should use MSVC name mangling rules. pub msvc_mangling: bool, + + /// The set of raw lines to prepend to the generated Rust code. pub raw_lines: Vec, + + /// The set of arguments to pass straight through to Clang. pub clang_args: Vec, } @@ -173,13 +268,18 @@ impl Default for BindgenOptions { } } +/// The linking type to use with a given library. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum LinkType { + /// Use shared library linking. This is the default. Default, + /// Use static linking. Static, + /// The library is an OSX framework. Framework } +/// Generated Rust bindings. #[derive(Debug, Clone)] pub struct Bindings { module: ast::Mod, @@ -187,7 +287,10 @@ pub struct Bindings { } impl Bindings { + /// Generate bindings for the given options. + /// /// Deprecated - use a `Builder` instead + #[deprecated] pub fn generate(options: BindgenOptions, span: Option) -> Result { let span = span.unwrap_or(DUMMY_SP); @@ -205,10 +308,12 @@ impl Bindings { }) } + /// Convert these bindings into a Rust AST. pub fn into_ast(self) -> Vec> { self.module.items } + /// Convert these bindings into source text (with raw lines prepended). pub fn to_string(&self) -> String { let mut mod_str = vec![]; { @@ -218,11 +323,13 @@ impl Bindings { String::from_utf8(mod_str).unwrap() } + /// Write these bindings as source text to a file. pub fn write_to_file>(&self, path: P) -> io::Result<()> { let file = try!(OpenOptions::new().write(true).truncate(true).create(true).open(path)); self.write(Box::new(file)) } + /// Write these bindings as source text to the given `Write`able. // https://github.com/Manishearth/rust-clippy/issues/740 #[cfg_attr(feature = "clippy", allow(needless_lifetimes))] pub fn write<'a>(&self, mut writer: Box) -> io::Result<()> { @@ -255,6 +362,7 @@ fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool { } } +/// Parse one `Item` from the Clang cursor. pub fn parse_one(ctx: &mut BindgenContext, cursor: clang::Cursor, parent: Option, @@ -274,6 +382,7 @@ pub fn parse_one(ctx: &mut BindgenContext, CXChildVisit_Continue } +/// Parse the Clang AST into our `Item` internal representation. fn parse(context: &mut BindgenContext) { use clang::Diagnostic; use clangll::*; From fcfb8e5dd336940afc20b13c74d0bc62c069992f Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 24 Oct 2016 14:31:07 -0700 Subject: [PATCH 2/2] Add TODO for not ignoring LinkType --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 8f89b44714..4a5e807678 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -269,6 +269,8 @@ impl Default for BindgenOptions { } /// The linking type to use with a given library. +/// +/// TODO: #104: This is ignored at the moment, but shouldn't be. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum LinkType { /// Use shared library linking. This is the default.