summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bin/bindgen.rs20
-rwxr-xr-xsrc/clang.rs25
-rwxr-xr-xsrc/codegen/mod.rs68
-rw-r--r--src/ir/context.rs16
-rw-r--r--src/ir/ty.rs14
-rwxr-xr-xsrc/lib.rs30
6 files changed, 126 insertions, 47 deletions
diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs
index c906efee..2dbb1690 100755
--- a/src/bin/bindgen.rs
+++ b/src/bin/bindgen.rs
@@ -8,7 +8,7 @@ extern crate log;
extern crate clang_sys;
extern crate rustc_serialize;
-use bindgen::{BindgenOptions, Bindings, ClangVersion, LinkType, clang_version};
+use bindgen::{BindgenOptions, Bindings, LinkType, clang_version};
use std::default::Default;
use std::env;
use std::fs;
@@ -63,10 +63,17 @@ Options:
--use-msvc-mangling Handle MSVC C++ ABI mangling; requires that
target be set to (i686|x86_64)-pc-win32
+ --no-convert-floats Don't convert floats automatically to f32/f64.
+
--raw-line=<raw> Add a raw line at the beginning of the output.
--no-unstable-rust Avoid generating unstable rust.
+ --use-core Use built-in types from core instead of std.
+
+ --ctypes-prefix=<prefix> Use the given prefix before the raw types
+ instead of ::std::os::raw::.
+
--opaque-type=<type> Mark a type as opaque.
--blacklist-type=<type> Mark a type as hidden.
@@ -180,9 +187,20 @@ fn parse_args_or_exit(args: Vec<String>) -> (BindgenOptions, Box<io::Write>) {
"--no-unstable-rust" => {
options.unstable_rust = false;
}
+ "--use-core" => {
+ options.use_core = true;
+ }
+ "--ctypes-prefix" => {
+ let prefix = iter.next()
+ .expect("--ctypes-prefix expects a prefix after it");
+ options.ctypes_prefix = Some(prefix);
+ }
"--emit-clang-ast" => {
options.emit_ast = true;
}
+ "--no-convert-floats" => {
+ options.convert_floats = false;
+ }
"--use-msvc-mangling" => {
options.msvc_mangling = true;
}
diff --git a/src/clang.rs b/src/clang.rs
index d9fbd7b8..e6d78123 100755
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -101,7 +101,9 @@ impl Cursor {
/// See documentation for `lexical_parent` for details on semantic vs
/// lexical parents.
pub fn fallible_semantic_parent(&self) -> Option<Cursor> {
- let sp = self.semantic_parent();
+ let sp = unsafe {
+ Cursor { x: clang_getCursorSemanticParent(self.x) }
+ };
if sp == *self || !sp.is_valid() {
return None;
}
@@ -113,11 +115,7 @@ impl Cursor {
/// See documentation for `lexical_parent` for details on semantic vs
/// lexical parents.
pub fn semantic_parent(&self) -> Cursor {
- unsafe {
- Cursor {
- x: clang_getCursorSemanticParent(self.x),
- }
- }
+ self.fallible_semantic_parent().unwrap()
}
/// Return the number of template arguments used by this cursor's referent,
@@ -157,17 +155,18 @@ impl Cursor {
/// Is the referent a top level construct?
pub fn is_toplevel(&self) -> bool {
- let mut semantic_parent = self.semantic_parent();
+ let mut semantic_parent = self.fallible_semantic_parent();
- while semantic_parent.kind() == CXCursor_Namespace ||
- semantic_parent.kind() == CXCursor_NamespaceAlias ||
- semantic_parent.kind() == CXCursor_NamespaceRef {
- semantic_parent = semantic_parent.semantic_parent();
+ while semantic_parent.is_some() &&
+ (semantic_parent.unwrap().kind() == CXCursor_Namespace ||
+ semantic_parent.unwrap().kind() == CXCursor_NamespaceAlias ||
+ semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) {
+ semantic_parent = semantic_parent.unwrap().fallible_semantic_parent();
}
let tu = self.translation_unit();
- // Yes, the second can happen with, e.g., macro definitions.
- semantic_parent == tu || semantic_parent == tu.semantic_parent()
+ // Yes, this can happen with, e.g., macro definitions.
+ semantic_parent == tu.fallible_semantic_parent()
}
/// Get the kind of referent this cursor is pointing to.
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index e7fa62ee..bf6af82b 100755
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -533,6 +533,7 @@ impl<'a> Bitfield<'a> {
let setter_name = ctx.ext_cx()
.ident_of(&format!("set_{}", &field_name));
let mask = ((1usize << width) - 1) << offset;
+ let prefix = ctx.trait_prefix();
// The transmute is unfortunate, but it's needed for enums in
// bitfields.
let item = quote_item!(ctx.ext_cx(),
@@ -540,7 +541,7 @@ impl<'a> Bitfield<'a> {
#[inline]
pub fn $getter_name(&self) -> $field_type {
unsafe {
- ::std::mem::transmute(
+ ::$prefix::mem::transmute(
(
(self.$field_ident &
($mask as $bitfield_type))
@@ -942,8 +943,9 @@ impl CodeGenerator for CompInfo {
if !template_args_used[i] {
let name = ctx.resolve_type(*ty).name().unwrap();
let ident = ctx.rust_ident(name);
+ let prefix = ctx.trait_prefix();
let phantom = quote_ty!(ctx.ext_cx(),
- ::std::marker::PhantomData<$ident>);
+ ::$prefix::marker::PhantomData<$ident>);
let field =
StructFieldBuilder::named(format!("_phantom_{}", i))
.pub_()
@@ -999,10 +1001,11 @@ impl CodeGenerator for CompInfo {
let fn_name = format!("bindgen_test_layout_{}", canonical_name);
let fn_name = ctx.rust_ident_raw(&fn_name);
let ident = ctx.rust_ident_raw(&canonical_name);
- let size_of_expr =
- quote_expr!(ctx.ext_cx(), ::std::mem::size_of::<$ident>());
- let align_of_expr =
- quote_expr!(ctx.ext_cx(), ::std::mem::align_of::<$ident>());
+ let prefix = ctx.trait_prefix();
+ let size_of_expr = quote_expr!(ctx.ext_cx(),
+ ::$prefix::mem::size_of::<$ident>());
+ let align_of_expr = quote_expr!(ctx.ext_cx(),
+ ::$prefix::mem::align_of::<$ident>());
let size = layout.size;
let align = layout.align;
let item = quote_item!(ctx.ext_cx(),
@@ -1414,7 +1417,13 @@ impl ItemToRustTy for Item {
fn raw_type(ctx: &BindgenContext, name: &str) -> P<ast::Ty> {
let ident = ctx.rust_ident_raw(&name);
- quote_ty!(ctx.ext_cx(), ::std::os::raw::$ident)
+ match ctx.options().ctypes_prefix {
+ Some(ref prefix) => {
+ let prefix = ctx.rust_ident_raw(prefix);
+ quote_ty!(ctx.ext_cx(), $prefix::$ident)
+ }
+ None => quote_ty!(ctx.ext_cx(), ::std::os::raw::$ident),
+ }
}
impl ToRustTy for Type {
@@ -1430,9 +1439,7 @@ impl ToRustTy for Type {
TypeKind::Void => raw!(c_void),
// TODO: we should do something smart with nullptr, or maybe *const
// c_void is enough?
- TypeKind::NullPtr => {
- quote_ty!(ctx.ext_cx(), *const ::std::os::raw::c_void)
- }
+ TypeKind::NullPtr => raw!(c_void).to_ptr(true, ctx.span()),
TypeKind::Int(ik) => {
match ik {
IntKind::Bool => aster::ty::TyBuilder::new().bool(),
@@ -1458,12 +1465,25 @@ impl ToRustTy for Type {
}
TypeKind::Float(fk) => {
use ir::ty::FloatKind;
- // TODO: we probably should just take the type layout into
- // account?
- match fk {
- FloatKind::Float => aster::ty::TyBuilder::new().f32(),
- FloatKind::Double | FloatKind::LongDouble => {
- aster::ty::TyBuilder::new().f64()
+ if ctx.options().convert_floats {
+ // TODO: we probably should just take the type layout into
+ // account?
+ //
+ // Also, maybe this one shouldn't be the default?
+ match fk {
+ FloatKind::Float => aster::ty::TyBuilder::new().f32(),
+ FloatKind::Double | FloatKind::LongDouble => {
+ aster::ty::TyBuilder::new().f64()
+ }
+ }
+ } else {
+ // FIXME: `c_longdouble` doesn't seem to be defined in some
+ // systems, so we use `c_double` directly.
+ match fk {
+ FloatKind::Float => raw!(c_float),
+ FloatKind::Double | FloatKind::LongDouble => {
+ raw!(c_double)
+ }
}
}
}
@@ -1755,10 +1775,12 @@ mod utils {
pub fn prepend_union_types(ctx: &BindgenContext,
result: &mut Vec<P<ast::Item>>) {
+ let prefix = ctx.trait_prefix();
let union_field_decl = quote_item!(ctx.ext_cx(),
#[derive(Debug)]
#[repr(C)]
- pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
+ pub struct __BindgenUnionField<T>(
+ ::$prefix::marker::PhantomData<T>);
)
.unwrap();
@@ -1766,24 +1788,24 @@ mod utils {
impl<T> __BindgenUnionField<T> {
#[inline]
pub fn new() -> Self {
- __BindgenUnionField(::std::marker::PhantomData)
+ __BindgenUnionField(::$prefix::marker::PhantomData)
}
#[inline]
pub unsafe fn as_ref(&self) -> &T {
- ::std::mem::transmute(self)
+ ::$prefix::mem::transmute(self)
}
#[inline]
pub unsafe fn as_mut(&mut self) -> &mut T {
- ::std::mem::transmute(self)
+ ::$prefix::mem::transmute(self)
}
}
)
.unwrap();
let union_field_default_impl = quote_item!(&ctx.ext_cx(),
- impl<T> ::std::default::Default for __BindgenUnionField<T> {
+ impl<T> ::$prefix::default::Default for __BindgenUnionField<T> {
#[inline]
fn default() -> Self {
Self::new()
@@ -1793,7 +1815,7 @@ mod utils {
.unwrap();
let union_field_clone_impl = quote_item!(&ctx.ext_cx(),
- impl<T> ::std::clone::Clone for __BindgenUnionField<T> {
+ impl<T> ::$prefix::clone::Clone for __BindgenUnionField<T> {
#[inline]
fn clone(&self) -> Self {
Self::new()
@@ -1803,7 +1825,7 @@ mod utils {
.unwrap();
let union_field_copy_impl = quote_item!(&ctx.ext_cx(),
- impl<T> ::std::marker::Copy for __BindgenUnionField<T> {}
+ impl<T> ::$prefix::marker::Copy for __BindgenUnionField<T> {}
)
.unwrap();
diff --git a/src/ir/context.rs b/src/ir/context.rs
index fc06375c..f11b387a 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -221,7 +221,7 @@ impl<'ctx> BindgenContext<'ctx> {
/// Mangles a name so it doesn't conflict with any keyword.
pub fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> {
use syntax::parse::token;
- let ident = self.rust_ident_raw(&name);
+ let ident = self.rust_ident_raw(name);
let token = token::Ident(ident);
if token.is_any_keyword() || name.contains("@") ||
name.contains("?") || name.contains("$") ||
@@ -242,9 +242,7 @@ impl<'ctx> BindgenContext<'ctx> {
}
/// Returns a mangled name as a rust identifier.
- pub fn rust_ident_raw<S>(&self, name: &S) -> Ident
- where S: Borrow<str>,
- {
+ pub fn rust_ident_raw(&self, name: &str) -> Ident {
self.ext_cx().ident_of(name.borrow())
}
@@ -912,6 +910,16 @@ impl<'ctx> BindgenContext<'ctx> {
to_iterate: to_iterate,
}
}
+
+ /// Convenient method for getting the prefix to use for most traits in
+ /// codegen depending on the `use_core` option.
+ pub fn trait_prefix(&self) -> Ident {
+ if self.options().use_core {
+ self.rust_ident_raw("core")
+ } else {
+ self.rust_ident_raw("std")
+ }
+ }
}
/// An iterator over whitelisted items.
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 2c1e5f8e..77dc61be 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -686,9 +686,10 @@ impl Type {
// process of resolving them.
CXType_MemberPointer |
CXType_Pointer => {
- let inner =
- Item::from_ty_or_ref(ty.pointee_type().unwrap(), location,
- parent_id, ctx);
+ let inner = Item::from_ty_or_ref(ty.pointee_type().unwrap(),
+ location,
+ parent_id,
+ ctx);
TypeKind::Pointer(inner)
}
CXType_BlockPointer => TypeKind::BlockPointer,
@@ -696,9 +697,10 @@ impl Type {
// can even add bindings for that, so huh.
CXType_RValueReference |
CXType_LValueReference => {
- let inner =
- Item::from_ty_or_ref(ty.pointee_type().unwrap(), location,
- parent_id, ctx);
+ let inner = Item::from_ty_or_ref(ty.pointee_type().unwrap(),
+ location,
+ parent_id,
+ ctx);
TypeKind::Reference(inner)
}
// XXX DependentSizedArray is wrong
diff --git a/src/lib.rs b/src/lib.rs
index a0eba4c0..03dac3cc 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -204,12 +204,30 @@ impl Builder {
self
}
+ /// Avoid converting floats to f32/f64 by default.
+ pub fn no_convert_floats(mut self) -> Self {
+ self.options.convert_floats = false;
+ self
+ }
+
/// Avoid generating any unstable Rust in the generated bindings.
pub fn no_unstable_rust(mut self) -> Builder {
self.options.unstable_rust = false;
self
}
+ /// Use core instead of libstd in the generated bindings.
+ pub fn use_core(mut self) -> Builder {
+ self.options.use_core = true;
+ self
+ }
+
+ /// Use the given prefix for the raw types instead of `::std::os::raw`.
+ pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
+ self.options.ctypes_prefix = Some(prefix.into());
+ self
+ }
+
/// Generate the Rust bindings using the options built up thus far.
pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
Bindings::generate(self.options, None)
@@ -273,6 +291,12 @@ pub struct BindgenOptions {
/// cannot.
pub unstable_rust: bool,
+ /// True if we should avoid using libstd to use libcore instead.
+ pub use_core: bool,
+
+ /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
+ pub ctypes_prefix: Option<String>,
+
/// True if we should generate constant names that are **directly** under
/// namespaces.
pub namespaced_constants: bool,
@@ -280,6 +304,9 @@ pub struct BindgenOptions {
/// True if we should use MSVC name mangling rules.
pub msvc_mangling: bool,
+ /// Whether we should convert float types to f32/f64 types.
+ pub convert_floats: bool,
+
/// The set of raw lines to prepend to the generated Rust code.
pub raw_lines: Vec<String>,
@@ -310,8 +337,11 @@ impl Default for BindgenOptions {
derive_debug: true,
enable_cxx_namespaces: false,
unstable_rust: true,
+ use_core: false,
+ ctypes_prefix: None,
namespaced_constants: true,
msvc_mangling: false,
+ convert_floats: true,
raw_lines: vec![],
clang_args: vec![],
input_header: None,