summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/derive_debug.rs197
-rw-r--r--src/codegen/mod.rs1656
-rw-r--r--src/lib.rs305
-rw-r--r--src/options.rs25
-rw-r--r--tests/expectations/tests/derive-debug-bitfield.rs119
-rw-r--r--tests/expectations/tests/derive-debug-function-pointer.rs47
-rw-r--r--tests/expectations/tests/derive-debug-generic.rs19
-rw-r--r--tests/expectations/tests/derive-debug-opaque-template-instantiation.rs30
-rw-r--r--tests/expectations/tests/derive-debug-opaque.rs49
-rw-r--r--tests/headers/derive-debug-bitfield.hpp7
-rw-r--r--tests/headers/derive-debug-function-pointer.hpp7
-rw-r--r--tests/headers/derive-debug-generic.hpp6
-rw-r--r--tests/headers/derive-debug-opaque-template-instantiation.hpp10
-rw-r--r--tests/headers/derive-debug-opaque.hpp10
14 files changed, 1610 insertions, 877 deletions
diff --git a/src/codegen/derive_debug.rs b/src/codegen/derive_debug.rs
new file mode 100644
index 00000000..a47d37d1
--- /dev/null
+++ b/src/codegen/derive_debug.rs
@@ -0,0 +1,197 @@
+use ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods};
+use ir::context::BindgenContext;
+use ir::derive::CanTriviallyDeriveDebug;
+use ir::item::{IsOpaque, Item, ItemCanonicalName};
+use ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
+use syntax::ast;
+use syntax::codemap::DUMMY_SP;
+use syntax::parse::token::Token;
+
+use syntax::tokenstream::TokenTree;
+
+pub fn gen_debug_impl(
+ ctx: &BindgenContext,
+ fields: &[Field],
+ item: &Item,
+ kind: CompKind,
+) -> Vec<ast::ImplItem> {
+ let struct_name = item.canonical_name(ctx);
+ let mut format_string = format!("{} {{{{ ", struct_name);
+ let mut tokens: Vec<TokenTree> = Vec::new();
+
+ if item.is_opaque(ctx, &()) {
+ format_string.push_str("opaque");
+ } else {
+ match kind {
+ CompKind::Union => {
+ format_string.push_str("union");
+ }
+ CompKind::Struct => {
+ let processed_fields = fields.iter().filter_map(|f| match f {
+ &Field::DataMember(ref fd) => {
+ gen_field_data_debug_impl(ctx, fd)
+ }
+ &Field::Bitfields(ref bu) => {
+ gen_bitfield_unit_debug_impl(ctx, bu)
+ }
+ });
+
+
+ for (i, (fstring, token)) in processed_fields.enumerate() {
+ if i > 0 {
+ format_string.push_str(", ");
+ }
+ if !token.is_empty() {
+ tokens.push(TokenTree::Token(DUMMY_SP, Token::Comma));
+ tokens.extend(token);
+ }
+ format_string.push_str(&fstring);
+ }
+ }
+ }
+ }
+
+ format_string.push_str(" }}");
+
+ let impl_ = quote_item!(ctx.ext_cx(),
+ impl X {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f, $format_string $tokens)
+ }
+ });
+
+ match impl_.unwrap().node {
+ ast::ItemKind::Impl(_, _, _, _, _, ref items) => items.clone(),
+ _ => unreachable!(),
+ }
+}
+
+fn gen_field_data_debug_impl(
+ ctx: &BindgenContext,
+ data: &FieldData,
+) -> Option<(String, Vec<TokenTree>)> {
+ if let Some(name) = data.name() {
+ gen_item_debug_impl(ctx, ctx.resolve_item(data.ty()), name)
+ } else {
+ None
+ }
+}
+
+fn gen_bitfield_unit_debug_impl(
+ ctx: &BindgenContext,
+ data: &BitfieldUnit,
+) -> Option<(String, Vec<TokenTree>)> {
+ let mut format_string = String::new();
+ let mut tokens = Vec::new();
+ for (i, bu) in data.bitfields().iter().enumerate() {
+ if i > 0 {
+ format_string.push_str(", ");
+ tokens.push(TokenTree::Token(DUMMY_SP, Token::Comma));
+ }
+ format_string.push_str(&format!("{} : {{:?}}", bu.name()));
+ let name_ident = ctx.rust_ident_raw(bu.name());
+ tokens.extend(quote_tokens!(ctx.ext_cx(), self.$name_ident()));
+ }
+
+ Some((format_string, tokens))
+}
+
+fn gen_item_debug_impl(
+ ctx: &BindgenContext,
+ item: &Item,
+ name: &str,
+) -> Option<(String, Vec<TokenTree>)> {
+ let name_ident = ctx.rust_ident_raw(name);
+
+ let ty = match item.as_type() {
+ Some(ty) => ty,
+ None => {
+ return None;
+ }
+ };
+
+ fn debug_print(
+ ctx: &BindgenContext,
+ name: &str,
+ name_ident: ast::Ident,
+ ) -> Option<(String, Vec<TokenTree>)> {
+ Some((
+ format!("{}: {{:?}}", name),
+ quote_tokens!(ctx.ext_cx(), self.$name_ident),
+ ))
+ }
+
+ match *ty.kind() {
+ // Handle the simple cases.
+ TypeKind::Void |
+ TypeKind::NullPtr |
+ TypeKind::Int(..) |
+ TypeKind::Float(..) |
+ TypeKind::Complex(..) |
+ TypeKind::Function(..) |
+ TypeKind::Enum(..) |
+ TypeKind::Reference(..) |
+ TypeKind::BlockPointer |
+ TypeKind::UnresolvedTypeRef(..) |
+ TypeKind::ObjCInterface(..) |
+ TypeKind::ObjCId |
+ TypeKind::Comp(..) |
+ TypeKind::ObjCSel => debug_print(ctx, name, name_ident),
+
+ TypeKind::TemplateInstantiation(ref inst) => {
+ if inst.is_opaque(ctx, item) {
+ Some((format!("{}: opaque", name), vec![]))
+ } else {
+ debug_print(ctx, name, name_ident)
+ }
+ }
+
+ // The generic is not required to implement Debug, so we can not debug print that type
+ TypeKind::Named => {
+ Some((format!("{}: Non-debuggable generic", name), vec![]))
+ }
+
+ TypeKind::Array(_, len) => {
+ // Generics are not required to implement Debug
+ if ctx.lookup_item_id_has_type_param_in_array(&item.id()) {
+ Some((format!("{}: Array with length {}", name, len), vec![]))
+ } else if len < RUST_DERIVE_IN_ARRAY_LIMIT {
+ // The simple case
+ debug_print(ctx, name, name_ident)
+ } else {
+ // Let's implement our own print function
+ Some((
+ format!("{}: [{{}}]", name),
+ quote_tokens!(
+ ctx.ext_cx(),
+ self.$name_ident
+ .iter()
+ .enumerate()
+ .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
+ .collect::<String>()),
+ ))
+ }
+ }
+
+ TypeKind::ResolvedTypeRef(t) |
+ TypeKind::TemplateAlias(t, _) |
+ TypeKind::Alias(t) => {
+ // We follow the aliases
+ gen_item_debug_impl(ctx, ctx.resolve_item(t), name)
+ }
+
+ TypeKind::Pointer(inner) => {
+ let inner_type = ctx.resolve_type(inner).canonical_type(ctx);
+ match *inner_type.kind() {
+ TypeKind::Function(ref sig)
+ if !sig.can_trivially_derive_debug() =>
+ {
+ Some((format!("{}: FunctionPointer", name), vec![]))
+ }
+ _ => debug_print(ctx, name, name_ident),
+ }
+ }
+
+ TypeKind::Opaque => None,
+ }
+}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 5c00a53d..7324a0ed 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1,17 +1,18 @@
+mod derive_debug;
mod error;
mod helpers;
pub mod struct_layout;
-use self::helpers::{BlobTyBuilder, attributes};
+use self::helpers::{attributes, BlobTyBuilder};
use self::struct_layout::StructLayoutTracker;
use aster;
use aster::struct_field::StructFieldBuilder;
use ir::annotations::FieldAccessorKind;
-use ir::comp::{Base, BitfieldUnit, Bitfield, CompInfo, CompKind, Field,
- FieldData, FieldMethods, Method, MethodKind};
use ir::comment;
+use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field,
+ FieldData, FieldMethods, Method, MethodKind};
use ir::context::{BindgenContext, ItemId};
use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
use ir::dot;
@@ -36,7 +37,7 @@ use std::mem;
use std::ops;
use syntax::abi;
use syntax::ast;
-use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::codemap::{respan, Span, DUMMY_SP};
use syntax::ptr::P;
// Name of type defined in constified enum module
@@ -181,7 +182,8 @@ impl<'a> CodegenResult<'a> {
}
fn inner<F>(&mut self, cb: F) -> Vec<P<ast::Item>>
- where F: FnOnce(&mut Self),
+ where
+ F: FnOnce(&mut Self),
{
let mut new = Self::new(self.codegen_id);
@@ -230,7 +232,8 @@ impl ForeignModBuilder {
#[allow(dead_code)]
fn with_foreign_items<I>(mut self, items: I) -> Self
- where I: IntoIterator<Item = ast::ForeignItem>,
+ where
+ I: IntoIterator<Item = ast::ForeignItem>,
{
self.inner.items.extend(items.into_iter());
self
@@ -279,27 +282,33 @@ trait CodeGenerator {
/// Extra information from the caller.
type Extra;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- extra: &Self::Extra);
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ extra: &Self::Extra,
+ );
}
impl CodeGenerator for Item {
type Extra = ();
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- _extra: &()) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ _extra: &(),
+ ) {
if !self.is_enabled_for_codegen(ctx) {
return;
}
if self.is_hidden(ctx) || result.seen(self.id()) {
- debug!("<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
- self = {:?}",
- self);
+ debug!(
+ "<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
+ self = {:?}",
+ self
+ );
return;
}
@@ -333,10 +342,12 @@ impl CodeGenerator for Item {
impl CodeGenerator for Module {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
let codegen_self = |result: &mut CodegenResult,
@@ -344,8 +355,7 @@ impl CodeGenerator for Module {
for child in self.children() {
if ctx.codegen_items().contains(child) {
*found_any = true;
- ctx.resolve_item(*child)
- .codegen(ctx, result, &());
+ ctx.resolve_item(*child).codegen(ctx, result, &());
}
}
@@ -366,7 +376,9 @@ impl CodeGenerator for Module {
};
if !ctx.options().enable_cxx_namespaces ||
- (self.is_inline() && !ctx.options().conservative_inline_namespaces) {
+ (self.is_inline() &&
+ !ctx.options().conservative_inline_namespaces)
+ {
codegen_self(result, &mut false);
return;
}
@@ -388,14 +400,15 @@ impl CodeGenerator for Module {
});
let name = item.canonical_name(ctx);
- let item_builder = aster::AstBuilder::new()
- .item()
- .pub_();
+ let item_builder = aster::AstBuilder::new().item().pub_();
let item = if name == "root" {
- let attrs = &["non_snake_case",
+ let attrs = &[
+ "non_snake_case",
"non_camel_case_types",
- "non_upper_case_globals"];
- item_builder.with_attr(attributes::allow(attrs))
+ "non_upper_case_globals",
+ ];
+ item_builder
+ .with_attr(attributes::allow(attrs))
.build_item_kind(name, module)
} else {
item_builder.build_item_kind(name, module)
@@ -407,10 +420,12 @@ impl CodeGenerator for Module {
impl CodeGenerator for Var {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
use ir::var::VarType;
debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
@@ -456,30 +471,23 @@ impl CodeGenerator for Var {
let ty = quote_ty!(ctx.ext_cx(), [u8; $len]);
match String::from_utf8(bytes.clone()) {
- Ok(string) => {
- const_item.build(helpers::ast_ty::cstr_expr(string))
- .build(quote_ty!(ctx.ext_cx(), &'static $ty))
- }
- Err(..) => {
- const_item
- .build(helpers::ast_ty::byte_array_expr(bytes))
- .build(ty)
- }
+ Ok(string) => const_item
+ .build(helpers::ast_ty::cstr_expr(string))
+ .build(quote_ty!(ctx.ext_cx(), &'static $ty)),
+ Err(..) => const_item
+ .build(helpers::ast_ty::byte_array_expr(bytes))
+ .build(ty),
}
}
VarType::Float(f) => {
match helpers::ast_ty::float_expr(ctx, f) {
- Ok(expr) => {
- const_item.build(expr).build(ty)
- }
+ Ok(expr) => const_item.build(expr).build(ty),
Err(..) => return,
}
}
- VarType::Char(c) => {
- const_item
- .build(aster::AstBuilder::new().expr().lit().byte(c))
- .build(ty)
- }
+ VarType::Char(c) => const_item
+ .build(aster::AstBuilder::new().expr().lit().byte(c))
+ .build(ty),
};
result.push(item);
@@ -511,10 +519,12 @@ impl CodeGenerator for Var {
impl CodeGenerator for Type {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
@@ -539,11 +549,8 @@ impl CodeGenerator for Type {
TypeKind::TemplateInstantiation(ref inst) => {
inst.codegen(ctx, result, item)
}
- TypeKind::Comp(ref ci) => {
- ci.codegen(ctx, result, item)
- }
- TypeKind::TemplateAlias(inner, _) |
- TypeKind::Alias(inner) => {
+ TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item),
+ TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => {
let inner_item = ctx.resolve_item(inner);
let name = item.canonical_name(ctx);
@@ -572,7 +579,8 @@ impl CodeGenerator for Type {
// Its possible that we have better layout information than
// the inner type does, so fall back to an opaque blob based
// on our layout if converting the inner item fails.
- inner_item.try_to_rust_ty_or_opaque(ctx, &())
+ inner_item
+ .try_to_rust_ty_or_opaque(ctx, &())
.unwrap_or_else(|_| self.to_opaque(ctx, item))
};
@@ -587,13 +595,15 @@ impl CodeGenerator for Type {
// with invalid template parameters, and at least this way
// they can be replaced, instead of generating plain invalid
// code.
- let inner_canon_type = inner_item.expect_type()
- .canonical_type(ctx);
+ let inner_canon_type =
+ inner_item.expect_type().canonical_type(ctx);
if inner_canon_type.is_invalid_named_type() {
- warn!("Item contained invalid named type, skipping: \
- {:?}, {:?}",
- item,
- inner_item);
+ warn!(
+ "Item contained invalid named type, skipping: \
+ {:?}, {:?}",
+ item,
+ inner_item
+ );
return;
}
}
@@ -608,27 +618,30 @@ impl CodeGenerator for Type {
// We prefer using `pub use` over `pub type` because of:
// https://github.com/rust-lang/rust/issues/26264
let simple_enum_path = match inner_rust_type.node {
- ast::TyKind::Path(None, ref p) => {
- if used_template_params.is_none() &&
- inner_item.expect_type()
+ ast::TyKind::Path(None, ref p) => if used_template_params
+ .is_none() &&
+ inner_item
+ .expect_type()
.canonical_type(ctx)
.is_enum() &&
- p.segments.iter().all(|p| p.parameters.is_none()) {
- Some(p.clone())
- } else {
- None
- }
- }
+ p.segments.iter().all(|p| p.parameters.is_none())
+ {
+ Some(p.clone())
+ } else {
+ None
+ },
_ => None,
};
let typedef = if let Some(mut p) = simple_enum_path {
for ident in top_level_path(ctx, item).into_iter().rev() {
- p.segments.insert(0,
- ast::PathSegment {
- identifier: ident,
- parameters: None,
- });
+ p.segments.insert(
+ 0,
+ ast::PathSegment {
+ identifier: ident,
+ parameters: None,
+ },
+ );
}
typedef.use_().build(p).as_(rust_name)
} else {
@@ -636,17 +649,21 @@ impl CodeGenerator for Type {
if let Some(ref params) = used_template_params {
for template_param in params {
if let Some(id) =
- template_param.as_template_param(ctx, &()) {
+ template_param.as_template_param(ctx, &())
+ {
let template_param = ctx.resolve_type(id);
if template_param.is_invalid_named_type() {
- warn!("Item contained invalid template \
- parameter: {:?}",
- item);
+ warn!(
+ "Item contained invalid template \
+ parameter: {:?}",
+ item
+ );
return;
}
generics =
- generics.ty_param_id(template_param.name()
- .unwrap());
+ generics.ty_param_id(
+ template_param.name().unwrap(),
+ );
}
}
}
@@ -654,9 +671,7 @@ impl CodeGenerator for Type {
};
result.push(typedef)
}
- TypeKind::Enum(ref ei) => {
- ei.codegen(ctx, result, item)
- }
+ TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item),
TypeKind::ObjCId | TypeKind::ObjCSel => {
result.saw_objc();
}
@@ -679,10 +694,11 @@ struct Vtable<'a> {
}
impl<'a> Vtable<'a> {
- fn new(item_id: ItemId,
- methods: &'a [Method],
- base_classes: &'a [Base])
- -> Self {
+ fn new(
+ item_id: ItemId,
+ methods: &'a [Method],
+ base_classes: &'a [Base],
+ ) -> Self {
Vtable {
item_id: item_id,
methods: methods,
@@ -694,10 +710,12 @@ impl<'a> Vtable<'a> {
impl<'a> CodeGenerator for Vtable<'a> {
type Extra = Item;
- fn codegen<'b>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'b>,
- item: &Item) {
+ fn codegen<'b>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'b>,
+ item: &Item,
+ ) {
assert_eq!(item.id(), self.item_id);
debug_assert!(item.is_enabled_for_codegen(ctx));
@@ -726,9 +744,11 @@ impl<'a> ItemCanonicalName for Vtable<'a> {
impl<'a> TryToRustTy for Vtable<'a> {
type Extra = ();
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- _: &()) -> error::Result<P<ast::Ty>> {
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ _: &(),
+ ) -> error::Result<P<ast::Ty>> {
Ok(aster::ty::TyBuilder::new().id(self.canonical_name(ctx)))
}
}
@@ -736,10 +756,12 @@ impl<'a> TryToRustTy for Vtable<'a> {
impl CodeGenerator for TemplateInstantiation {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug_assert!(item.is_enabled_for_codegen(ctx));
// Although uses of instantiations don't need code generation, and are
@@ -749,7 +771,7 @@ impl CodeGenerator for TemplateInstantiation {
// properly understand it (maybe because of specializations), and so we
// shouldn't emit layout tests either.
if !ctx.options().layout_tests || self.is_opaque(ctx, item) {
- return
+ return;
}
// If there are any unbound type parameters, then we can't generate a
@@ -766,7 +788,8 @@ impl CodeGenerator for TemplateInstantiation {
let align = layout.align;
let name = item.full_disambiguated_name(ctx);
- let mut fn_name = format!("__bindgen_test_layout_{}_instantiation", name);
+ let mut fn_name =
+ format!("__bindgen_test_layout_{}_instantiation", name);
let times_seen = result.overload_number(&fn_name);
if times_seen > 0 {
write!(&mut fn_name, "_{}", times_seen).unwrap();
@@ -791,8 +814,7 @@ impl CodeGenerator for TemplateInstantiation {
assert_eq!($align_of_expr, $align,
concat!("Alignment of template specialization: ",
stringify!($ident)));
- })
- .unwrap();
+ }).unwrap();
result.push(item);
}
@@ -821,66 +843,74 @@ impl Iterator for AnonFieldNames {
trait FieldCodegen<'a> {
type Extra;
- fn codegen<F, M>(&self,
- ctx: &BindgenContext,
- fields_should_be_private: bool,
- codegen_depth: usize,
- accessor_kind: FieldAccessorKind,
- parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
- result: &mut CodegenResult,
- struct_layout: &mut StructLayoutTracker,
- fields: &mut F,
- methods: &mut M,
- extra: Self::Extra)
- where F: Extend<ast::StructField>,
- M: Extend<ast::ImplItem>;
+ fn codegen<F, M>(
+ &self,
+ ctx: &BindgenContext,
+ fields_should_be_private: bool,
+ codegen_depth: usize,
+ accessor_kind: FieldAccessorKind,
+ parent: &CompInfo,
+ anon_field_names: &mut AnonFieldNames,
+ result: &mut CodegenResult,
+ struct_layout: &mut StructLayoutTracker,
+ fields: &mut F,
+ methods: &mut M,
+ extra: Self::Extra,
+ ) where
+ F: Extend<ast::StructField>,
+ M: Extend<ast::ImplItem>;
}
impl<'a> FieldCodegen<'a> for Field {
type Extra = ();
- fn codegen<F, M>(&self,
- ctx: &BindgenContext,
- fields_should_be_private: bool,
- codegen_depth: usize,
- accessor_kind: FieldAccessorKind,
- parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
- result: &mut CodegenResult,
- struct_layout: &mut StructLayoutTracker,
- fields: &mut F,
- methods: &mut M,
- _: ())
- where F: Extend<ast::StructField>,
- M: Extend<ast::ImplItem>
+ fn codegen<F, M>(
+ &self,
+ ctx: &BindgenContext,
+ fields_should_be_private: bool,
+ codegen_depth: usize,
+ accessor_kind: FieldAccessorKind,
+ parent: &CompInfo,
+ anon_field_names: &mut AnonFieldNames,
+ result: &mut CodegenResult,
+ struct_layout: &mut StructLayoutTracker,
+ fields: &mut F,
+ methods: &mut M,
+ _: (),
+ ) where
+ F: Extend<ast::StructField>,
+ M: Extend<ast::ImplItem>,
{
match *self {
Field::DataMember(ref data) => {
- data.codegen(ctx,
- fields_should_be_private,
- codegen_depth,
- accessor_kind,
- parent,
- anon_field_names,
- result,
- struct_layout,
- fields,
- methods,
- ());
+ data.codegen(
+ ctx,
+ fields_should_be_private,
+ codegen_depth,
+ accessor_kind,
+ parent,
+ anon_field_names,
+ result,
+ struct_layout,
+ fields,
+ methods,
+ (),
+ );
}
Field::Bitfields(ref unit) => {
- unit.codegen(ctx,
- fields_should_be_private,
- codegen_depth,
- accessor_kind,
- parent,
- anon_field_names,
- result,
- struct_layout,
- fields,
- methods,
- ());
+ unit.codegen(
+ ctx,
+ fields_should_be_private,
+ codegen_depth,
+ accessor_kind,
+ parent,
+ anon_field_names,
+ result,
+ struct_layout,
+ fields,
+ methods,
+ (),
+ );
}
}
}
@@ -889,20 +919,22 @@ impl<'a> FieldCodegen<'a> for Field {
impl<'a> FieldCodegen<'a> for FieldData {
type Extra = ();
- fn codegen<F, M>(&self,
- ctx: &BindgenContext,
- fields_should_be_private: bool,
- codegen_depth: usize,
- accessor_kind: FieldAccessorKind,
- parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
- result: &mut CodegenResult,
- struct_layout: &mut StructLayoutTracker,
- fields: &mut F,
- methods: &mut M,
- _: ())
- where F: Extend<ast::StructField>,
- M: Extend<ast::ImplItem>
+ fn codegen<F, M>(
+ &self,
+ ctx: &BindgenContext,
+ fields_should_be_private: bool,
+ codegen_depth: usize,
+ accessor_kind: FieldAccessorKind,
+ parent: &CompInfo,
+ anon_field_names: &mut AnonFieldNames,
+ result: &mut CodegenResult,
+ struct_layout: &mut StructLayoutTracker,
+ fields: &mut F,
+ methods: &mut M,
+ _: (),
+ ) where
+ F: Extend<ast::StructField>,
+ M: Extend<ast::ImplItem>,
{
// Bitfields are handled by `FieldCodegen` implementations for
// `BitfieldUnit` and `Bitfield`.
@@ -918,8 +950,7 @@ impl<'a> FieldCodegen<'a> for FieldData {
} else {
quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>)
}
- } else if let Some(item) =
- field_ty.is_incomplete_array(ctx) {
+ } else if let Some(item) = field_ty.is_incomplete_array(ctx) {
result.saw_incomplete_array();
let inner = item.to_rust_ty_or_opaque(ctx, &());
@@ -936,7 +967,8 @@ impl<'a> FieldCodegen<'a> for FieldData {
let mut attrs = vec![];
if ctx.options().generate_comments {
if let Some(raw_comment) = self.comment() {
- let comment = comment::preprocess(raw_comment, codegen_depth + 1);
+ let comment =
+ comment::preprocess(raw_comment, codegen_depth + 1);
attrs.push(attributes::doc(comment))
}
}
@@ -947,7 +979,8 @@ impl<'a> FieldCodegen<'a> for FieldData {
if !parent.is_union() {
if let Some(padding_field) =
- struct_layout.pad_field(&field_name, field_ty, self.offset()) {
+ struct_layout.pad_field(&field_name, field_ty, self.offset())
+ {
fields.extend(Some(padding_field));
}
}
@@ -956,9 +989,8 @@ impl<'a> FieldCodegen<'a> for FieldData {
.private_fields()
.unwrap_or(fields_should_be_private);
- let accessor_kind = self.annotations()
- .accessor_kind()
- .unwrap_or(accessor_kind);
+ let accessor_kind =
+ self.annotations().accessor_kind().unwrap_or(accessor_kind);
let mut field = StructFieldBuilder::named(&field_name);
@@ -966,8 +998,7 @@ impl<'a> FieldCodegen<'a> for FieldData {
field = field.pub_();
}
- let field = field.with_attrs(attrs)
- .build_ty(ty.clone());
+ let field = field.with_attrs(attrs).build_ty(ty.clone());
fields.extend(Some(field));
@@ -976,16 +1007,14 @@ impl<'a> FieldCodegen<'a> for FieldData {
return;
}
- let getter_name =
- ctx.rust_ident_raw(&format!("get_{}", field_name));
+ let getter_name = ctx.rust_ident_raw(&format!("get_{}", field_name));
let mutable_getter_name =
ctx.rust_ident_raw(&format!("get_{}_mut", field_name));
let field_name = ctx.rust_ident_raw(&field_name);
let accessor_methods_impl = match accessor_kind {
FieldAccessorKind::None => unreachable!(),
- FieldAccessorKind::Regular => {
- quote_item!(ctx.ext_cx(),
+ FieldAccessorKind::Regular => quote_item!(ctx.ext_cx(),
impl X {
#[inline]
pub fn $getter_name(&self) -> &$ty {
@@ -997,10 +1026,8 @@ impl<'a> FieldCodegen<'a> for FieldData {
&mut self.$field_name
}
}
- )
- }
- FieldAccessorKind::Unsafe => {
- quote_item!(ctx.ext_cx(),
+ ),
+ FieldAccessorKind::Unsafe => quote_item!(ctx.ext_cx(),
impl X {
#[inline]
pub unsafe fn $getter_name(&self) -> &$ty {
@@ -1013,18 +1040,15 @@ impl<'a> FieldCodegen<'a> for FieldData {
&mut self.$field_name
}
}
- )
- }
- FieldAccessorKind::Immutable => {
- quote_item!(ctx.ext_cx(),
+ ),
+ FieldAccessorKind::Immutable => quote_item!(ctx.ext_cx(),
impl X {
#[inline]
pub fn $getter_name(&self) -> &$ty {
&self.$field_name
}
}
- )
- }
+ ),
};
match accessor_methods_impl.unwrap().node {
@@ -1046,10 +1070,11 @@ impl BitfieldUnit {
/// Get the initial bitfield unit constructor that just returns 0. This will
/// then be extended by each bitfield in the unit. See `extend_ctor_impl`
/// below.
- fn initial_ctor_impl(&self,
- ctx: &BindgenContext,
- unit_field_int_ty: &P<ast::Ty>)
- -> P<ast::Item> {
+ fn initial_ctor_impl(
+ &self,
+ ctx: &BindgenContext,
+ unit_field_int_ty: &P<ast::Ty>,
+ ) -> P<ast::Item> {
let ctor_name = self.ctor_name(ctx);
// If we're generating unstable Rust, add the const.
@@ -1079,25 +1104,22 @@ impl Bitfield {
///
/// 2. Bitwise or'ing the parameter into the final value of the constructed
/// bitfield unit.
- fn extend_ctor_impl(&self,
- ctx: &BindgenContext,
- parent: &CompInfo,
- ctor_impl: P<ast::Item>,
- ctor_name: &ast::Ident,
- unit_field_int_ty: &P<ast::Ty>)
- -> P<ast::Item> {
+ fn extend_ctor_impl(
+ &self,
+ ctx: &BindgenContext,
+ parent: &CompInfo,
+ ctor_impl: P<ast::Item>,
+ ctor_name: &ast::Ident,
+ unit_field_int_ty: &P<ast::Ty>,
+ ) -> P<ast::Item> {
let items = match ctor_impl.unwrap().node {
- ast::ItemKind::Impl(_, _, _, _, _, items) => {
- items
- }
+ ast::ItemKind::Impl(_, _, _, _, _, items) => items,
_ => unreachable!(),
};
assert_eq!(items.len(), 1);
let (sig, body) = match items[0].node {
- ast::ImplItemKind::Method(ref sig, ref body) => {
- (sig, body)
- }
+ ast::ImplItemKind::Method(ref sig, ref body) => (sig, body),
_ => unreachable!(),
};
@@ -1106,11 +1128,12 @@ impl Bitfield {
let bitfield_ty_item = ctx.resolve_item(self.ty());
let bitfield_ty = bitfield_ty_item.expect_type();
- let bitfield_ty_layout = bitfield_ty.layout(ctx)
+ let bitfield_ty_layout = bitfield_ty
+ .layout(ctx)
.expect("Bitfield without layout? Gah!");
let bitfield_int_ty = BlobTyBuilder::new(bitfield_ty_layout).build();
- let bitfield_ty = bitfield_ty
- .to_rust_ty_or_opaque(ctx, bitfield_ty_item);
+ let bitfield_ty =
+ bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item);
let offset = self.offset_into_unit();
let mask = self.mask();
@@ -1141,20 +1164,22 @@ impl Bitfield {
impl<'a> FieldCodegen<'a> for BitfieldUnit {
type Extra = ();
- fn codegen<F, M>(&self,
- ctx: &BindgenContext,
- fields_should_be_private: bool,
- codegen_depth: usize,
- accessor_kind: FieldAccessorKind,
- parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
- result: &mut CodegenResult,
- struct_layout: &mut StructLayoutTracker,
- fields: &mut F,
- methods: &mut M,
- _: ())
- where F: Extend<ast::StructField>,
- M: Extend<ast::ImplItem>
+ fn codegen<F, M>(
+ &self,
+ ctx: &BindgenContext,
+ fields_should_be_private: bool,
+ codegen_depth: usize,
+ accessor_kind: FieldAccessorKind,
+ parent: &CompInfo,
+ anon_field_names: &mut AnonFieldNames,
+ result: &mut CodegenResult,
+ struct_layout: &mut StructLayoutTracker,
+ fields: &mut F,
+ methods: &mut M,
+ _: (),
+ ) where
+ F: Extend<ast::StructField>,
+ M: Extend<ast::ImplItem>,
{
let field_ty = BlobTyBuilder::new(self.layout()).build();
let unit_field_name = format!("_bitfield_{}", self.nth());
@@ -1187,30 +1212,34 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
let mut ctor_impl = self.initial_ctor_impl(ctx, &unit_field_int_ty);
for bf in self.bitfields() {
- bf.codegen(ctx,
- fields_should_be_private,
- codegen_depth,
- accessor_kind,
- parent,
- anon_field_names,
- result,
- struct_layout,
- fields,
- methods,
- (&unit_field_name, unit_field_int_ty.clone()));
-
- ctor_impl = bf.extend_ctor_impl(ctx,
- parent,
- ctor_impl,
- &ctor_name,
- &unit_field_int_ty);
+ bf.codegen(
+ ctx,
+ fields_should_be_private,
+ codegen_depth,
+ accessor_kind,
+ parent,
+ anon_field_names,
+ result,
+ struct_layout,
+ fields,
+ methods,
+ (&unit_field_name, unit_field_int_ty.clone()),
+ );
+
+ ctor_impl = bf.extend_ctor_impl(
+ ctx,
+ parent,
+ ctor_impl,
+ &ctor_name,
+ &unit_field_int_ty,
+ );
}
match ctor_impl.unwrap().node {
ast::ItemKind::Impl(_, _, _, _, _, items) => {
assert_eq!(items.len(), 1);
methods.extend(items.into_iter());
- },
+ }
_ => unreachable!(),
};
@@ -1218,27 +1247,31 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
}
}
-fn parent_has_method(ctx: &BindgenContext,
- parent: &CompInfo,
- name: &str)
- -> bool {
+fn parent_has_method(
+ ctx: &BindgenContext,
+ parent: &CompInfo,
+ name: &str,
+) -> bool {
parent.methods().iter().any(|method| {
let method_name = match *ctx.resolve_item(method.signature()).kind() {
ItemKind::Function(ref func) => func.name(),
- ref otherwise => panic!("a method's signature should always be a \
- item of kind ItemKind::Function, found: \
- {:?}",
- otherwise),
+ ref otherwise => panic!(
+ "a method's signature should always be a \
+ item of kind ItemKind::Function, found: \
+ {:?}",
+ otherwise
+ ),
};
method_name == name || ctx.rust_mangle(&method_name) == name
})
}
-fn bitfield_getter_name(ctx: &BindgenContext,
- parent: &CompInfo,
- bitfield_name: &str)
- -> ast::Ident {
+fn bitfield_getter_name(
+ ctx: &BindgenContext,
+ parent: &CompInfo,
+ bitfield_name: &str,
+) -> ast::Ident {
let name = ctx.rust_mangle(bitfield_name);
if parent_has_method(ctx, parent, &name) {
@@ -1250,10 +1283,11 @@ fn bitfield_getter_name(ctx: &BindgenContext,
ctx.ext_cx().ident_of(&name)
}
-fn bitfield_setter_name(ctx: &BindgenContext,
- parent: &CompInfo,
- bitfield_name: &str)
- -> ast::Ident {
+fn bitfield_setter_name(
+ ctx: &BindgenContext,
+ parent: &CompInfo,
+ bitfield_name: &str,
+) -> ast::Ident {
let setter = format!("set_{}", bitfield_name);
let mut setter = ctx.rust_mangle(&setter).to_string();
@@ -1267,21 +1301,22 @@ fn bitfield_setter_name(ctx: &BindgenContext,
impl<'a> FieldCodegen<'a> for Bitfield {
type Extra = (&'a str, P<ast::Ty>);
- fn codegen<F, M>(&self,
- ctx: &BindgenContext,
- _fields_should_be_private: bool,
- _codegen_depth: usize,
- _accessor_kind: FieldAccessorKind,
- parent: &CompInfo,
- _anon_field_names: &mut AnonFieldNames,
- _result: &mut CodegenResult,
- _struct_layout: &mut StructLayoutTracker,
- _fields: &mut F,
- methods: &mut M,
- (unit_field_name,
- unit_field_int_ty): (&'a str, P<ast::Ty>))
- where F: Extend<ast::StructField>,
- M: Extend<ast::ImplItem>
+ fn codegen<F, M>(
+ &self,
+ ctx: &BindgenContext,
+ _fields_should_be_private: bool,
+ _codegen_depth: usize,
+ _accessor_kind: FieldAccessorKind,
+ parent: &CompInfo,
+ _anon_field_names: &mut AnonFieldNames,
+ _result: &mut CodegenResult,
+ _struct_layout: &mut StructLayoutTracker,
+ _fields: &mut F,
+ methods: &mut M,
+ (unit_field_name, unit_field_int_ty): (&'a str, P<ast::Ty>),
+ ) where
+ F: Extend<ast::StructField>,
+ M: Extend<ast::ImplItem>,
{
let prefix = ctx.trait_prefix();
let getter_name = bitfield_getter_name(ctx, parent, self.name());
@@ -1291,11 +1326,13 @@ impl<'a> FieldCodegen<'a> for Bitfield {
let bitfield_ty_item = ctx.resolve_item(self.ty());
let bitfield_ty = bitfield_ty_item.expect_type();
- let bitfield_ty_layout = bitfield_ty.layout(ctx)
+ let bitfield_ty_layout = bitfield_ty
+ .layout(ctx)
.expect("Bitfield without layout? Gah!");
let bitfield_int_ty = BlobTyBuilder::new(bitfield_ty_layout).build();
- let bitfield_ty = bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item);
+ let bitfield_ty =
+ bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item);
let offset = self.offset_into_unit();
let mask = self.mask();
@@ -1358,7 +1395,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
match impl_item.unwrap().node {
ast::ItemKind::Impl(_, _, _, _, _, items) => {
methods.extend(items.into_iter());
- },
+ }
_ => unreachable!(),
};
}
@@ -1367,10 +1404,12 @@ impl<'a> FieldCodegen<'a> for Bitfield {
impl CodeGenerator for CompInfo {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug!("<CompInfo as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
@@ -1403,6 +1442,7 @@ impl CodeGenerator for CompInfo {
let mut attributes = vec![];
let mut needs_clone_impl = false;
let mut needs_default_impl = false;
+ let mut needs_debug_impl = false;
if let Some(comment) = item.comment(ctx) {
attributes.push(attributes::doc(comment));
}
@@ -1416,6 +1456,9 @@ impl CodeGenerator for CompInfo {
let mut derives = vec![];
if item.can_derive_debug(ctx) {
derives.push("Debug");
+ } else {
+ needs_debug_impl =
+ ctx.options().derive_debug && ctx.options().impl_debug
}
if item.can_derive_default(ctx) {
@@ -1424,8 +1467,7 @@ impl CodeGenerator for CompInfo {
needs_default_impl = ctx.options().derive_default;
}
- if item.can_derive_copy(ctx) &&
- !item.annotations().disallow_copy() {
+ if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
derives.push("Copy");
if used_template_params.is_some() {
// FIXME: This requires extra logic if you have a big array in a
@@ -1472,13 +1514,15 @@ impl CodeGenerator for CompInfo {
// Also, we need to generate the vtable in such a way it "inherits" from
// the parent too.
let mut fields = vec![];
- let mut struct_layout = StructLayoutTracker::new(ctx, self, &canonical_name);
+ let mut struct_layout =
+ StructLayoutTracker::new(ctx, self, &canonical_name);
if self.needs_explicit_vtable(ctx, item) {
let vtable =
Vtable::new(item.id(), self.methods(), self.base_members());
vtable.codegen(ctx, result, item);
- let vtable_type = vtable.try_to_rust_ty(ctx, &())
+ let vtable_type = vtable
+ .try_to_rust_ty(ctx, &())
.expect("vtable to Rust type conversion is infallible")
.to_ptr(true, ctx.span());
@@ -1517,9 +1561,8 @@ impl CodeGenerator for CompInfo {
struct_layout.saw_base(base_ty);
- let field = StructFieldBuilder::named(field_name)
- .pub_()
- .build_ty(inner);
+ let field =
+ StructFieldBuilder::named(field_name).pub_().build_ty(inner);
fields.extend(Some(field));
}
if is_union {
@@ -1528,9 +1571,8 @@ impl CodeGenerator for CompInfo {
let layout = item.kind().expect_type().layout(ctx);
- let fields_should_be_private = item.annotations()
- .private_fields()
- .unwrap_or(false);
+ let fields_should_be_private =
+ item.annotations().private_fields().unwrap_or(false);
let struct_accessor_kind = item.annotations()
.accessor_kind()
.unwrap_or(FieldAccessorKind::None);
@@ -1539,17 +1581,19 @@ impl CodeGenerator for CompInfo {
let mut anon_field_names = AnonFieldNames::default();
let codegen_depth = item.codegen_depth(ctx);
for field in self.fields() {
- field.codegen(ctx,
- fields_should_be_private,
- codegen_depth,
- struct_accessor_kind,
- self,
- &mut anon_field_names,
- result,
- &mut struct_layout,
- &mut fields,
- &mut methods,
- ());
+ field.codegen(
+ ctx,
+ fields_should_be_private,
+ codegen_depth,
+ struct_accessor_kind,
+ self,
+ &mut anon_field_names,
+ result,
+ &mut struct_layout,
+ &mut fields,
+ &mut methods,
+ (),
+ );
}
if is_union && !ctx.options().unstable_rust {
@@ -1573,10 +1617,10 @@ impl CodeGenerator for CompInfo {
match layout {
Some(l) => {
let ty = BlobTyBuilder::new(l).build();
- let field =
- StructFieldBuilder::named("_bindgen_opaque_blob")
- .pub_()
- .build_ty(ty);
+ let field = StructFieldBuilder::named(
+ "_bindgen_opaque_blob",
+ ).pub_()
+ .build_ty(ty);
fields.push(field);
}
None => {
@@ -1585,14 +1629,14 @@ impl CodeGenerator for CompInfo {
}
} else if !is_union && !self.is_unsized(ctx, &item.id()) {
if let Some(padding_field) =
- layout.and_then(|layout| {
- struct_layout.pad_struct(layout)
- }) {
+ layout.and_then(|layout| struct_layout.pad_struct(layout))
+ {
fields.push(padding_field);
}
if let Some(align_field) =
- layout.and_then(|layout| struct_layout.align_struct(layout)) {
+ layout.and_then(|layout| struct_layout.align_struct(layout))
+ {
fields.push(align_field);
}
}
@@ -1618,9 +1662,8 @@ impl CodeGenerator for CompInfo {
if has_address {
let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
- let field = StructFieldBuilder::named("_address")
- .pub_()
- .build_ty(ty);
+ let field =
+ StructFieldBuilder::named("_address").pub_().build_ty(ty);
fields.push(field);
}
}
@@ -1639,8 +1682,9 @@ impl CodeGenerator for CompInfo {
let phantom_ty = quote_ty!(
ctx.ext_cx(),
::$prefix::marker::PhantomData<::$prefix::cell::UnsafeCell<$ident>>);
- let phantom_field = StructFieldBuilder::named(format!("_phantom_{}", idx))
- .pub_()
+ let phantom_field = StructFieldBuilder::named(
+ format!("_phantom_{}", idx),
+ ).pub_()
.build_ty(phantom_ty);
fields.push(phantom_field);
}
@@ -1648,7 +1692,8 @@ impl CodeGenerator for CompInfo {
let generics = generics.build();
- let rust_struct = builder.with_generics(generics.clone())
+ let rust_struct = builder
+ .with_generics(generics.clone())
.with_fields(fields)
.build();
result.push(rust_struct);
@@ -1667,21 +1712,23 @@ impl CodeGenerator for CompInfo {
// affect layout, so we're bad and pray to the gods for avoid sending
// all the tests to shit when parsing things like max_align_t.
if self.found_unknown_attr() {
- warn!("Type {} has an unkown attribute that may affect layout",
- canonical_name);
+ warn!(
+ "Type {} has an unkown attribute that may affect layout",
+ canonical_name
+ );
}
if used_template_params.is_none() {
if !is_opaque {
for var in self.inner_vars() {
- ctx.resolve_item(*var)
- .codegen(ctx, result, &());
+ ctx.resolve_item(*var).codegen(ctx, result, &());
}
}
if ctx.options().layout_tests {
if let Some(layout) = layout {
- let fn_name = format!("bindgen_test_layout_{}", canonical_name);
+ let fn_name =
+ format!("bindgen_test_layout_{}", canonical_name);
let fn_name = ctx.rust_ident_raw(&fn_name);
let type_name = ctx.rust_ident_raw(&canonical_name);
let prefix = ctx.trait_prefix();
@@ -1692,32 +1739,33 @@ impl CodeGenerator for CompInfo {
let size = layout.size;
let align = layout.align;
- let check_struct_align = if align > mem::size_of::<*mut ()>() {
- // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
- None
- } else {
- quote_item!(ctx.ext_cx(),
+ let check_struct_align =
+ if align > mem::size_of::<*mut ()>() {
+ // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
+ None
+ } else {
+ quote_item!(ctx.ext_cx(),
assert_eq!($align_of_expr,
$align,
concat!("Alignment of ", stringify!($type_name)));
)
- };
+ };
// FIXME when [issue #465](https://github.com/rust-lang-nursery/rust-bindgen/issues/465) ready
let too_many_base_vtables = self.base_members()
.iter()
- .filter(|base| {
- ctx.lookup_item_id_has_vtable(&base.ty)
- })
- .count() > 1;
+ .filter(|base| ctx.lookup_item_id_has_vtable(&base.ty))
+ .count() >
+ 1;
let should_skip_field_offset_checks =
is_opaque || too_many_base_vtables;
- let check_field_offset = if should_skip_field_offset_checks {
- None
- } else {
- let asserts = self.fields()
+ let check_field_offset =
+ if should_skip_field_offset_checks {
+ None
+ } else {
+ let asserts = self.fields()
.iter()
.filter_map(|field| match *field {
Field::DataMember(ref f) if f.name().is_some() => Some(f),
@@ -1738,8 +1786,8 @@ impl CodeGenerator for CompInfo {
})
.collect::<Vec<P<ast::Item>>>();
- Some(asserts)
- };
+ Some(asserts)
+ };
let item = quote_item!(ctx.ext_cx(),
#[test]
@@ -1760,25 +1808,30 @@ impl CodeGenerator for CompInfo {
if ctx.options().codegen_config.methods {
for method in self.methods() {
assert!(method.kind() != MethodKind::Constructor);
- method.codegen_method(ctx,
- &mut methods,
- &mut method_names,
- result,
- self);
+ method.codegen_method(
+ ctx,
+ &mut methods,
+ &mut method_names,
+ result,
+ self,
+ );
}
}
if ctx.options().codegen_config.constructors {
for sig in self.constructors() {
- Method::new(MethodKind::Constructor,
- *sig,
- /* const */
- false)
- .codegen_method(ctx,
- &mut methods,
- &mut method_names,
- result,
- self);
+ Method::new(
+ MethodKind::Constructor,
+ *sig,
+ /* const */
+ false,
+ ).codegen_method(
+ ctx,
+ &mut methods,
+ &mut method_names,
+ result,
+ self,
+ );
}
}
@@ -1790,12 +1843,13 @@ impl CodeGenerator for CompInfo {
MethodKind::Destructor
};
- Method::new(kind, destructor, false)
- .codegen_method(ctx,
- &mut methods,
- &mut method_names,
- result,
- self);
+ Method::new(kind, destructor, false).codegen_method(
+ ctx,
+ &mut methods,
+ &mut method_names,
+ result,
+ self,
+ );
}
}
}
@@ -1861,6 +1915,27 @@ impl CodeGenerator for CompInfo {
result.push(default_impl);
}
+ if needs_debug_impl {
+ let impl_ = derive_debug::gen_debug_impl(
+ ctx,
+ self.fields(),
+ item,
+ self.kind(),
+ );
+
+ let debug_impl = aster::AstBuilder::new()
+ .item()
+ .impl_()
+ .trait_()
+ .id("::std::fmt::Debug")
+ .build()
+ .with_generics(generics.clone())
+ .with_items(impl_)
+ .build_ty(ty_for_impl.clone());
+
+ result.push(debug_impl);
+ }
+
if !methods.is_empty() {
let methods = aster::AstBuilder::new()
.item()
@@ -1874,30 +1949,34 @@ impl CodeGenerator for CompInfo {
}
trait MethodCodegen {
- fn codegen_method<'a>(&self,
- ctx: &BindgenContext,
- methods: &mut Vec<ast::ImplItem>,
- method_names: &mut HashMap<String, usize>,
- result: &mut CodegenResult<'a>,
- parent: &CompInfo);
+ fn codegen_method<'a>(
+ &self,
+ ctx: &BindgenContext,
+ methods: &mut Vec<ast::ImplItem>,
+ method_names: &mut HashMap<String, usize>,
+ result: &mut CodegenResult<'a>,
+ parent: &CompInfo,
+ );
}
impl MethodCodegen for Method {
- fn codegen_method<'a>(&self,
- ctx: &BindgenContext,
- methods: &mut Vec<ast::ImplItem>,
- method_names: &mut HashMap<String, usize>,
- result: &mut CodegenResult<'a>,
- _parent: &CompInfo) {
+ fn codegen_method<'a>(
+ &self,
+ ctx: &BindgenContext,
+ methods: &mut Vec<ast::ImplItem>,
+ method_names: &mut HashMap<String, usize>,
+ result: &mut CodegenResult<'a>,
+ _parent: &CompInfo,
+ ) {
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::Static | MethodKind::Normal | MethodKind::Virtual => {
+ cc.methods
+ }
}
});
@@ -1929,8 +2008,7 @@ impl MethodCodegen for Method {
}
let count = {
- let mut count = method_names.entry(name.clone())
- .or_insert(0);
+ let mut count = method_names.entry(name.clone()).or_insert(0);
*count += 1;
*count - 1
};
@@ -1940,8 +2018,8 @@ impl MethodCodegen for Method {
}
let function_name = function_item.canonical_name(ctx);
- let mut fndecl = utils::rust_fndecl_from_signature(ctx, signature_item)
- .unwrap();
+ let mut fndecl =
+ utils::rust_fndecl_from_signature(ctx, signature_item).unwrap();
if !self.is_static() && !self.is_constructor() {
let mutability = if self.is_const() {
ast::Mutability::Immutable
@@ -1955,14 +2033,17 @@ impl MethodCodegen for Method {
fndecl.inputs[0] = ast::Arg {
ty: P(ast::Ty {
id: ast::DUMMY_NODE_ID,
- node: ast::TyKind::Rptr(None, ast::MutTy {
- ty: P(ast::Ty {
- id: ast::DUMMY_NODE_ID,
- node: ast::TyKind::ImplicitSelf,
- span: ctx.span()
- }),
- mutbl: mutability,
- }),
+ node: ast::TyKind::Rptr(
+ None,
+ ast::MutTy {
+ ty: P(ast::Ty {
+ id: ast::DUMMY_NODE_ID,
+ node: ast::TyKind::ImplicitSelf,
+ span: ctx.span(),
+ }),
+ mutbl: mutability,
+ },
+ ),
span: ctx.span(),
}),
pat: P(ast::Pat {
@@ -1970,7 +2051,7 @@ impl MethodCodegen for Method {
node: ast::PatKind::Ident(
ast::BindingMode::ByValue(ast::Mutability::Immutable),
respan(ctx.span(), ctx.ext_cx().ident_of("self")),
- None
+ None,
),
span: ctx.span(),
}),
@@ -1985,8 +2066,8 @@ impl MethodCodegen for Method {
// return-type = void.
if self.is_constructor() {
fndecl.inputs.remove(0);
- fndecl.output = ast::FunctionRetTy::Ty(quote_ty!(ctx.ext_cx(),
- Self));
+ fndecl.output =
+ ast::FunctionRetTy::Ty(quote_ty!(ctx.ext_cx(), Self));
}
let sig = ast::MethodSig {
@@ -1997,8 +2078,8 @@ impl MethodCodegen for Method {
constness: respan(ctx.span(), ast::Constness::NotConst),
};
- let mut exprs = helpers::ast_ty::arguments_from_signature(&signature,
- ctx);
+ let mut exprs =
+ helpers::ast_ty::arguments_from_signature(&signature, ctx);
let mut stmts = vec![];
@@ -2074,17 +2155,19 @@ enum EnumBuilder<'a> {
impl<'a> EnumBuilder<'a> {
/// Create a new enum given an item builder, a canonical name, a name for
/// the representation, and whether it should be represented as a rust enum.
- fn new(aster: aster::item::ItemBuilder<aster::invoke::Identity>,
- name: &'a str,
- repr: P<ast::Ty>,
- bitfield_like: bool,
- constify: bool,
- constify_module: bool)
- -> Self {
+ fn new(
+ aster: aster::item::ItemBuilder<aster::invoke::Identity>,
+ name: &'a str,
+ repr: P<ast::Ty>,
+ bitfield_like: bool,
+ constify: bool,
+ constify_module: bool,
+ ) -> Self {
if bitfield_like {
EnumBuilder::Bitfield {
canonical_name: name,
- aster: aster.tuple_struct(name)
+ aster: aster
+ .tuple_struct(name)
.field()
.pub_()
.build_ty(repr)
@@ -2101,7 +2184,7 @@ impl<'a> EnumBuilder<'a> {
module_name: name,
module_items: vec![type_definition],
}
- } else {
+ } else {
EnumBuilder::Consts {
aster: aster.type_(name).build_ty(repr),
}
@@ -2112,13 +2195,14 @@ impl<'a> EnumBuilder<'a> {
}
/// Add a variant to this enum.
- fn with_variant<'b>(self,
- ctx: &BindgenContext,
- variant: &EnumVariant,
- mangling_prefix: Option<&String>,
- rust_ty: P<ast::Ty>,
- result: &mut CodegenResult<'b>)
- -> Self {
+ fn with_variant<'b>(
+ self,
+ ctx: &BindgenContext,
+ variant: &EnumVariant,
+ mangling_prefix: Option<&String>,
+ rust_ty: P<ast::Ty>,
+ result: &mut CodegenResult<'b>,
+ ) -> Self {
let variant_name = ctx.rust_mangle(variant.name());
let expr = aster::AstBuilder::new().expr();
let expr = match variant.val() {
@@ -2135,7 +2219,9 @@ impl<'a> EnumBuilder<'a> {
disr_expr: Some(expr),
}))
}
- EnumBuilder::Bitfield { canonical_name, .. } => {
+ EnumBuilder::Bitfield {
+ canonical_name, ..
+ } => {
let constant_name = match mangling_prefix {
Some(prefix) => {
Cow::Owned(format!("{}_{}", prefix, variant_name))
@@ -2157,7 +2243,9 @@ impl<'a> EnumBuilder<'a> {
result.push(constant);
self
}
- EnumBuilder::Consts { .. } => {
+ EnumBuilder::Consts {
+ ..
+ } => {
let constant_name = match mangling_prefix {
Some(prefix) => {
Cow::Owned(format!("{}_{}", prefix, variant_name))
@@ -2176,10 +2264,15 @@ impl<'a> EnumBuilder<'a> {
result.push(constant);
self
}
- EnumBuilder::ModuleConsts { module_name, module_items, .. } => {
+ EnumBuilder::ModuleConsts {
+ module_name,
+ module_items,
+ ..
+ } => {
// Variant type
- let inside_module_type =
- aster::AstBuilder::new().ty().id(CONSTIFIED_ENUM_MODULE_REPR_NAME);
+ let inside_module_type = aster::AstBuilder::new()
+ .ty()
+ .id(CONSTIFIED_ENUM_MODULE_REPR_NAME);
let constant = aster::AstBuilder::new()
.item()
@@ -2200,14 +2293,18 @@ impl<'a> EnumBuilder<'a> {
}
}
- fn build<'b>(self,
- ctx: &BindgenContext,
- rust_ty: P<ast::Ty>,
- result: &mut CodegenResult<'b>)
- -> P<ast::Item> {
+ fn build<'b>(
+ self,
+ ctx: &BindgenContext,
+ rust_ty: P<ast::Ty>,
+ result: &mut CodegenResult<'b>,
+ ) -> P<ast::Item> {
match self {
EnumBuilder::Rust(b) => b.build(),
- EnumBuilder::Bitfield { canonical_name, aster } => {
+ EnumBuilder::Bitfield {
+ canonical_name,
+ aster,
+ } => {
let rust_ty_name = ctx.rust_ident_raw(canonical_name);
let prefix = ctx.trait_prefix();
@@ -2220,8 +2317,7 @@ impl<'a> EnumBuilder<'a> {
$rust_ty_name(self.0 | other.0)
}
}
- )
- .unwrap();
+ ).unwrap();
result.push(impl_);
let impl_ = quote_item!(ctx.ext_cx(),
@@ -2231,8 +2327,7 @@ impl<'a> EnumBuilder<'a> {
self.0 |= rhs.0;
}
}
- )
- .unwrap();
+ ).unwrap();
result.push(impl_);
let impl_ = quote_item!(ctx.ext_cx(),
@@ -2244,8 +2339,7 @@ impl<'a> EnumBuilder<'a> {
$rust_ty_name(self.0 & other.0)
}
}
- )
- .unwrap();
+ ).unwrap();
result.push(impl_);
let impl_ = quote_item!(ctx.ext_cx(),
@@ -2255,14 +2349,19 @@ impl<'a> EnumBuilder<'a> {
self.0 &= rhs.0;
}
}
- )
- .unwrap();
+ ).unwrap();
result.push(impl_);
aster
}
- EnumBuilder::Consts { aster, .. } => aster,
- EnumBuilder::ModuleConsts { module_items, module_name, .. } => {
+ EnumBuilder::Consts {
+ aster, ..
+ } => aster,
+ EnumBuilder::ModuleConsts {
+ module_items,
+ module_name,
+ ..
+ } => {
// Create module item with type and variant definitions
let module_item = P(ast::Item {
ident: ast::Ident::from_str(module_name),
@@ -2285,10 +2384,12 @@ impl<'a> EnumBuilder<'a> {
impl CodeGenerator for Enum {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
@@ -2298,21 +2399,22 @@ impl CodeGenerator for Enum {
let repr = self.repr().map(|repr| ctx.resolve_type(repr));
let repr = match repr {
- Some(repr) => {
- match *repr.canonical_type(ctx).kind() {
- TypeKind::Int(int_kind) => int_kind,
- _ => panic!("Unexpected type as enum repr"),
- }
- }
+ Some(repr) => match *repr.canonical_type(ctx).kind() {
+ TypeKind::Int(int_kind) => int_kind,
+ _ => panic!("Unexpected type as enum repr"),
+ },
None => {
- warn!("Guessing type of enum! Forward declarations of enums \
- shouldn't be legal!");
+ warn!(
+ "Guessing type of enum! Forward declarations of enums \
+ shouldn't be legal!"
+ );
IntKind::Int
}
};
let signed = repr.is_signed();
- let size = layout.map(|l| l.size)
+ let size = layout
+ .map(|l| l.size)
.or_else(|| repr.known_size())
.unwrap_or(0);
@@ -2337,21 +2439,22 @@ impl CodeGenerator for Enum {
// disambiguate between namespaces, just like is_opaque etc.
let is_bitfield = {
ctx.options().bitfield_enums.matches(&name) ||
- (enum_ty.name().is_none() &&
- self.variants()
- .iter()
- .any(|v| ctx.options().bitfield_enums.matches(&v.name())))
+ (enum_ty.name().is_none() &&
+ self.variants().iter().any(
+ |v| ctx.options().bitfield_enums.matches(&v.name()),
+ ))
};
- let is_constified_enum_module = self.is_constified_enum_module(ctx, item);
+ let is_constified_enum_module =
+ self.is_constified_enum_module(ctx, item);
- let is_constified_enum = {
+ let is_constified_enum = {
is_constified_enum_module ||
- ctx.options().constified_enums.matches(&name) ||
- (enum_ty.name().is_none() &&
- self.variants()
- .iter()
- .any(|v| ctx.options().constified_enums.matches(&v.name())))
+ ctx.options().constified_enums.matches(&name) ||
+ (enum_ty.name().is_none() &&
+ self.variants().iter().any(
+ |v| ctx.options().constified_enums.matches(&v.name()),
+ ))
};
let is_rust_enum = !is_bitfield && !is_constified_enum;
@@ -2373,27 +2476,26 @@ impl CodeGenerator for Enum {
}
if !is_constified_enum {
- let derives = attributes::derives(&["Debug",
- "Copy",
- "Clone",
- "PartialEq",
- "Eq",
- "Hash"]);
+ let derives = attributes::derives(
+ &["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"],
+ );
builder = builder.with_attr(derives);
}
- fn add_constant<'a>(ctx: &BindgenContext,
- enum_: &Type,
- // Only to avoid recomputing every time.
- enum_canonical_name: &str,
- // May be the same as "variant" if it's because the
- // enum is unnamed and we still haven't seen the
- // value.
- variant_name: &str,
- referenced_name: &str,
- enum_rust_ty: P<ast::Ty>,
- result: &mut CodegenResult<'a>) {
+ fn add_constant<'a>(
+ ctx: &BindgenContext,
+ enum_: &Type,
+ // Only to avoid recomputing every time.
+ enum_canonical_name: &str,
+ // May be the same as "variant" if it's because the
+ // enum is unnamed and we still haven't seen the
+ // value.
+ variant_name: &str,
+ referenced_name: &str,
+ enum_rust_ty: P<ast::Ty>,
+ result: &mut CodegenResult<'a>,
+ ) {
let constant_name = if enum_.name().is_some() {
if ctx.options().prepend_enum_name {
format!("{}_{}", enum_canonical_name, variant_name)
@@ -2420,12 +2522,14 @@ impl CodeGenerator for Enum {
.and_then(|repr| repr.try_to_rust_ty_or_opaque(ctx, &()).ok())
.unwrap_or_else(|| helpers::ast_ty::raw_type(ctx, repr_name));
- let mut builder = EnumBuilder::new(builder,
- &name,
- repr,
- is_bitfield,
- is_constified_enum,
- is_constified_enum_module);
+ let mut builder = EnumBuilder::new(
+ builder,
+ &name,
+ repr,
+ is_bitfield,
+ is_constified_enum,
+ is_constified_enum_module,
+ );
// A map where we keep a value -> variant relation.
let mut seen_values = HashMap::<_, String>::new();
@@ -2455,8 +2559,9 @@ impl CodeGenerator for Enum {
let mut constified_variants = VecDeque::new();
let mut iter = self.variants().iter().peekable();
- while let Some(variant) = iter.next()
- .or_else(|| constified_variants.pop_front()) {
+ while let Some(variant) =
+ iter.next().or_else(|| constified_variants.pop_front())
+ {
if variant.hidden() {
continue;
}
@@ -2467,43 +2572,46 @@ impl CodeGenerator for Enum {
}
match seen_values.entry(variant.val()) {
- Entry::Occupied(ref entry) => {
- if is_rust_enum {
- let variant_name = ctx.rust_mangle(variant.name());
- let mangled_name = if is_toplevel ||
- enum_ty.name().is_some() {
- variant_name
- } else {
- let parent_name = parent_canonical_name.as_ref()
- .unwrap();
+ Entry::Occupied(ref entry) => if is_rust_enum {
+ let variant_name = ctx.rust_mangle(variant.name());
+ let mangled_name = if is_toplevel ||
+ enum_ty.name().is_some()
+ {
+ variant_name
+ } else {
+ let parent_name =
+ parent_canonical_name.as_ref().unwrap();
- Cow::Owned(format!("{}_{}",
- parent_name,
- variant_name))
- };
+ Cow::Owned(format!("{}_{}", parent_name, variant_name))
+ };
- let existing_variant_name = entry.get();
- add_constant(ctx,
- enum_ty,
- &name,
- &*mangled_name,
- existing_variant_name,
- enum_rust_ty.clone(),
- result);
- } else {
- builder = builder.with_variant(ctx,
- variant,
- constant_mangling_prefix,
- enum_rust_ty.clone(),
- result);
- }
- }
+ let existing_variant_name = entry.get();
+ add_constant(
+ ctx,
+ enum_ty,
+ &name,
+ &*mangled_name,
+ existing_variant_name,
+ enum_rust_ty.clone(),
+ result,
+ );
+ } else {
+ builder = builder.with_variant(
+ ctx,
+ variant,
+ constant_mangling_prefix,
+ enum_rust_ty.clone(),
+ result,
+ );
+ },
Entry::Vacant(entry) => {
- builder = builder.with_variant(ctx,
- variant,
- constant_mangling_prefix,
- enum_rust_ty.clone(),
- result);
+ builder = builder.with_variant(
+ ctx,
+ variant,
+ constant_mangling_prefix,
+ enum_rust_ty.clone(),
+ result,
+ );
let variant_name = ctx.rust_mangle(variant.name());
@@ -2511,25 +2619,28 @@ impl CodeGenerator for Enum {
// we also generate a constant so it can be properly
// accessed.
if (is_rust_enum && enum_ty.name().is_none()) ||
- variant.force_constification() {
+ variant.force_constification()
+ {
let mangled_name = if is_toplevel {
variant_name.clone()
} else {
- let parent_name = parent_canonical_name.as_ref()
- .unwrap();
+ let parent_name =
+ parent_canonical_name.as_ref().unwrap();
- Cow::Owned(format!("{}_{}",
- parent_name,
- variant_name))
+ Cow::Owned(
+ format!("{}_{}", parent_name, variant_name),
+ )
};
- add_constant(ctx,
- enum_ty,
- &name,
- &mangled_name,
- &variant_name,
- enum_rust_ty.clone(),
- result);
+ add_constant(
+ ctx,
+ enum_ty,
+ &name,
+ &mangled_name,
+ &variant_name,
+ enum_rust_ty.clone(),
+ result,
+ );
}
entry.insert(variant_name.into_owned());
@@ -2551,16 +2662,18 @@ trait TryToOpaque {
type Extra;
/// Get the layout for this thing, if one is available.
- fn try_get_layout(&self,
- ctx: &BindgenContext,
- extra: &Self::Extra)
- -> error::Result<Layout>;
+ fn try_get_layout(
+ &self,
+ ctx: &BindgenContext,
+ extra: &Self::Extra,
+ ) -> error::Result<Layout>;
/// Do not override this provided trait method.
- fn try_to_opaque(&self,
- ctx: &BindgenContext,
- extra: &Self::Extra)
- -> error::Result<P<ast::Ty>> {
+ fn try_to_opaque(
+ &self,
+ ctx: &BindgenContext,
+ extra: &Self::Extra,
+ ) -> error::Result<P<ast::Ty>> {
self.try_get_layout(ctx, extra)
.map(|layout| BlobTyBuilder::new(layout).build())
}
@@ -2577,26 +2690,26 @@ trait TryToOpaque {
/// Don't implement this directly. Instead implement `TryToOpaque`, and then
/// leverage the blanket impl for this trait.
trait ToOpaque: TryToOpaque {
- fn get_layout(&self,
- ctx: &BindgenContext,
- extra: &Self::Extra)
- -> Layout {
+ fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout {
self.try_get_layout(ctx, extra)
.unwrap_or_else(|_| Layout::for_size(1))
}
- fn to_opaque(&self,
- ctx: &BindgenContext,
- extra: &Self::Extra)
- -> P<ast::Ty> {
+ fn to_opaque(
+ &self,
+ ctx: &BindgenContext,
+ extra: &Self::Extra,
+ ) -> P<ast::Ty> {
let layout = self.get_layout(ctx, extra);
BlobTyBuilder::new(layout).build()
}
}
impl<T> ToOpaque for T
- where T: TryToOpaque
-{}
+where
+ T: TryToOpaque,
+{
+}
/// Fallible conversion from an IR thing to an *equivalent* Rust type.
///
@@ -2608,10 +2721,11 @@ impl<T> ToOpaque for T
trait TryToRustTy {
type Extra;
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- extra: &Self::Extra)
- -> error::Result<P<ast::Ty>>;
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ extra: &Self::Extra,
+ ) -> error::Result<P<ast::Ty>>;
}
/// Fallible conversion to a Rust type or an opaque blob with the correct size
@@ -2622,29 +2736,31 @@ trait TryToRustTy {
trait TryToRustTyOrOpaque: TryToRustTy + TryToOpaque {
type Extra;
- fn try_to_rust_ty_or_opaque(&self,
- ctx: &BindgenContext,
- extra: &<Self as TryToRustTyOrOpaque>::Extra)
- -> error::Result<P<ast::Ty>>;
+ fn try_to_rust_ty_or_opaque(
+ &self,
+ ctx: &BindgenContext,
+ extra: &<Self as TryToRustTyOrOpaque>::Extra,
+ ) -> error::Result<P<ast::Ty>>;
}
impl<E, T> TryToRustTyOrOpaque for T
- where T: TryToRustTy<Extra=E> + TryToOpaque<Extra=E>
+where
+ T: TryToRustTy<Extra = E> + TryToOpaque<Extra = E>,
{
type Extra = E;
- fn try_to_rust_ty_or_opaque(&self,
- ctx: &BindgenContext,
- extra: &E)
- -> error::Result<P<ast::Ty>> {
- self.try_to_rust_ty(ctx, extra)
- .or_else(|_| {
- if let Ok(layout) = self.try_get_layout(ctx, extra) {
- Ok(BlobTyBuilder::new(layout).build())
- } else {
- Err(error::Error::NoLayoutForOpaqueBlob)
- }
- })
+ fn try_to_rust_ty_or_opaque(
+ &self,
+ ctx: &BindgenContext,
+ extra: &E,
+ ) -> error::Result<P<ast::Ty>> {
+ self.try_to_rust_ty(ctx, extra).or_else(
+ |_| if let Ok(layout) = self.try_get_layout(ctx, extra) {
+ Ok(BlobTyBuilder::new(layout).build())
+ } else {
+ Err(error::Error::NoLayoutForOpaqueBlob)
+ },
+ )
}
}
@@ -2668,21 +2784,24 @@ impl<E, T> TryToRustTyOrOpaque for T
trait ToRustTyOrOpaque: TryToRustTy + ToOpaque {
type Extra;
- fn to_rust_ty_or_opaque(&self,
- ctx: &BindgenContext,
- extra: &<Self as ToRustTyOrOpaque>::Extra)
- -> P<ast::Ty>;
+ fn to_rust_ty_or_opaque(
+ &self,
+ ctx: &BindgenContext,
+ extra: &<Self as ToRustTyOrOpaque>::Extra,
+ ) -> P<ast::Ty>;
}
impl<E, T> ToRustTyOrOpaque for T
- where T: TryToRustTy<Extra=E> + ToOpaque<Extra=E>
+where
+ T: TryToRustTy<Extra = E> + ToOpaque<Extra = E>,
{
type Extra = E;
- fn to_rust_ty_or_opaque(&self,
- ctx: &BindgenContext,
- extra: &E)
- -> P<ast::Ty> {
+ fn to_rust_ty_or_opaque(
+ &self,
+ ctx: &BindgenContext,
+ extra: &E,
+ ) -> P<ast::Ty> {
self.try_to_rust_ty(ctx, extra)
.unwrap_or_else(|_| self.to_opaque(ctx, extra))
}
@@ -2691,10 +2810,11 @@ impl<E, T> ToRustTyOrOpaque for T
impl TryToOpaque for ItemId {
type Extra = ();
- fn try_get_layout(&self,
- ctx: &BindgenContext,
- _: &())
- -> error::Result<Layout> {
+ fn try_get_layout(
+ &self,
+ ctx: &BindgenContext,
+ _: &(),
+ ) -> error::Result<Layout> {
ctx.resolve_item(*self).try_get_layout(ctx, &())
}
}
@@ -2702,10 +2822,11 @@ impl TryToOpaque for ItemId {
impl TryToRustTy for ItemId {
type Extra = ();
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- _: &())
- -> error::Result<P<ast::Ty>> {
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ _: &(),
+ ) -> error::Result<P<ast::Ty>> {
ctx.resolve_item(*self).try_to_rust_ty(ctx, &())
}
}
@@ -2713,10 +2834,11 @@ impl TryToRustTy for ItemId {
impl TryToOpaque for Item {
type Extra = ();
- fn try_get_layout(&self,
- ctx: &BindgenContext,
- _: &())
- -> error::Result<Layout> {
+ fn try_get_layout(
+ &self,
+ ctx: &BindgenContext,
+ _: &(),
+ ) -> error::Result<Layout> {
self.kind().expect_type().try_get_layout(ctx, self)
}
}
@@ -2724,10 +2846,11 @@ impl TryToOpaque for Item {
impl TryToRustTy for Item {
type Extra = ();
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- _: &())
- -> error::Result<P<ast::Ty>> {
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ _: &(),
+ ) -> error::Result<P<ast::Ty>> {
self.kind().expect_type().try_to_rust_ty(ctx, self)
}
}
@@ -2735,10 +2858,11 @@ impl TryToRustTy for Item {
impl TryToOpaque for Type {
type Extra = Item;
- fn try_get_layout(&self,
- ctx: &BindgenContext,
- _: &Item)
- -> error::Result<Layout> {
+ fn try_get_layout(
+ &self,
+ ctx: &BindgenContext,
+ _: &Item,
+ ) -> error::Result<Layout> {
self.layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob)
}
}
@@ -2746,10 +2870,11 @@ impl TryToOpaque for Type {
impl TryToRustTy for Type {
type Extra = Item;
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- item: &Item)
- -> error::Result<P<ast::Ty>> {
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ item: &Item,
+ ) -> error::Result<P<ast::Ty>> {
use self::helpers::ast_ty::*;
match *self.kind() {
@@ -2762,7 +2887,9 @@ impl TryToRustTy for Type {
TypeKind::Int(ik) => {
match ik {
IntKind::Bool => Ok(aster::ty::TyBuilder::new().bool()),
- IntKind::Char { .. } => Ok(raw_type(ctx, "c_char")),
+ IntKind::Char {
+ ..
+ } => Ok(raw_type(ctx, "c_char")),
IntKind::SChar => Ok(raw_type(ctx, "c_schar")),
IntKind::UChar => Ok(raw_type(ctx, "c_uchar")),
IntKind::Short => Ok(raw_type(ctx, "c_short")),
@@ -2782,7 +2909,9 @@ impl TryToRustTy for Type {
IntKind::U32 => Ok(aster::ty::TyBuilder::new().u32()),
IntKind::I64 => Ok(aster::ty::TyBuilder::new().i64()),
IntKind::U64 => Ok(aster::ty::TyBuilder::new().u64()),
- IntKind::Custom { name, .. } => {
+ IntKind::Custom {
+ name, ..
+ } => {
let ident = ctx.rust_ident_raw(name);
Ok(quote_ty!(ctx.ext_cx(), $ident))
}
@@ -2821,18 +2950,13 @@ impl TryToRustTy for Type {
}
TypeKind::Enum(..) => {
let path = item.namespace_aware_canonical_path(ctx);
- Ok(aster::AstBuilder::new()
- .ty()
- .path()
- .ids(path)
- .build())
+ Ok(aster::AstBuilder::new().ty().path().ids(path).build())
}
TypeKind::TemplateInstantiation(ref inst) => {
inst.try_to_rust_ty(ctx, item)
}
TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()),
- TypeKind::TemplateAlias(inner, _) |
- TypeKind::Alias(inner) => {
+ TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => {
let template_params = item.used_template_params(ctx)
.unwrap_or(vec![])
.into_iter()
@@ -2842,9 +2966,9 @@ impl TryToRustTy for Type {
let spelling = self.name().expect("Unnamed alias?");
if item.is_opaque(ctx, &()) && !template_params.is_empty() {
self.try_to_opaque(ctx, item)
- } else if let Some(ty) = utils::type_from_named(ctx,
- spelling,
- inner) {
+ } else if let Some(ty) =
+ utils::type_from_named(ctx, spelling, inner)
+ {
Ok(ty)
} else {
utils::build_templated_path(item, ctx, template_params)
@@ -2853,26 +2977,24 @@ impl TryToRustTy for Type {
TypeKind::Comp(ref info) => {
let template_params = item.used_template_params(ctx);
if info.has_non_type_template_params() ||
- (item.is_opaque(ctx, &()) && template_params.is_some()) {
+ (item.is_opaque(ctx, &()) && template_params.is_some())
+ {
return self.try_to_opaque(ctx, item);
}
let template_params = template_params.unwrap_or(vec![]);
- utils::build_templated_path(item,
- ctx,
- template_params)
- }
- TypeKind::Opaque => {
- self.try_to_opaque(ctx, item)
+ utils::build_templated_path(item, ctx, template_params)
}
+ TypeKind::Opaque => self.try_to_opaque(ctx, item),
TypeKind::BlockPointer => {
let void = raw_type(ctx, "c_void");
- Ok(void.to_ptr(/* is_const = */
- false,
- ctx.span()))
+ Ok(void.to_ptr(
+ /* is_const = */
+ false,
+ ctx.span(),
+ ))
}
- TypeKind::Pointer(inner) |
- TypeKind::Reference(inner) => {
+ TypeKind::Pointer(inner) | TypeKind::Reference(inner) => {
let inner = ctx.resolve_item(inner);
let inner_ty = inner.expect_type();
@@ -2886,8 +3008,8 @@ impl TryToRustTy for Type {
if inner_ty.canonical_type(ctx).is_function() {
Ok(ty)
} else {
- let is_const = self.is_const() ||
- inner.expect_type().is_const();
+ let is_const =
+ self.is_const() || inner.expect_type().is_const();
Ok(ty.to_ptr(is_const, ctx.span()))
}
}
@@ -2896,9 +3018,12 @@ impl TryToRustTy for Type {
let ident = ctx.rust_ident(&name);
Ok(quote_ty!(ctx.ext_cx(), $ident))
}
- TypeKind::ObjCSel => Ok(quote_ty!(ctx.ext_cx(), objc::runtime::Sel)),
- TypeKind::ObjCId |
- TypeKind::ObjCInterface(..) => Ok(quote_ty!(ctx.ext_cx(), id)),
+ TypeKind::ObjCSel => {
+ Ok(quote_ty!(ctx.ext_cx(), objc::runtime::Sel))
+ }
+ TypeKind::ObjCId | TypeKind::ObjCInterface(..) => {
+ Ok(quote_ty!(ctx.ext_cx(), id))
+ }
ref u @ TypeKind::UnresolvedTypeRef(..) => {
unreachable!("Should have been resolved after parsing {:?}!", u)
}
@@ -2909,21 +3034,25 @@ impl TryToRustTy for Type {
impl TryToOpaque for TemplateInstantiation {
type Extra = Item;
- fn try_get_layout(&self,
- ctx: &BindgenContext,
- item: &Item)
- -> error::Result<Layout> {
- item.expect_type().layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob)
+ fn try_get_layout(
+ &self,
+ ctx: &BindgenContext,
+ item: &Item,
+ ) -> error::Result<Layout> {
+ item.expect_type()
+ .layout(ctx)
+ .ok_or(error::Error::NoLayoutForOpaqueBlob)
}
}
impl TryToRustTy for TemplateInstantiation {
type Extra = Item;
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- item: &Item)
- -> error::Result<P<ast::Ty>> {
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ item: &Item,
+ ) -> error::Result<P<ast::Ty>> {
if self.is_opaque(ctx, item) {
return Err(error::Error::InstantiationOfOpaqueType);
}
@@ -2937,10 +3066,12 @@ impl TryToRustTy for TemplateInstantiation {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
- extra_assert!(decl.into_resolver()
- .through_type_refs()
- .resolve(ctx)
- .is_opaque(ctx, &()));
+ extra_assert!(
+ decl.into_resolver()
+ .through_type_refs()
+ .resolve(ctx)
+ .is_opaque(ctx, &())
+ );
return Err(error::Error::InstantiationOfOpaqueType);
}
};
@@ -2963,18 +3094,18 @@ impl TryToRustTy for TemplateInstantiation {
.map(|(arg, _)| arg.try_to_rust_ty(ctx, &()))
.collect::<error::Result<Vec<_>>>()?;
- path.segments.last_mut().unwrap().parameters = if
- template_args.is_empty() {
- None
- } else {
- Some(P(ast::PathParameters::AngleBracketed(
- ast::AngleBracketedParameterData {
- lifetimes: vec![],
- types: template_args,
- bindings: vec![],
- }
- )))
- }
+ path.segments.last_mut().unwrap().parameters =
+ if template_args.is_empty() {
+ None
+ } else {
+ Some(P(ast::PathParameters::AngleBracketed(
+ ast::AngleBracketedParameterData {
+ lifetimes: vec![],
+ types: template_args,
+ bindings: vec![],
+ },
+ )))
+ }
}
Ok(P(ty))
@@ -2984,10 +3115,11 @@ impl TryToRustTy for TemplateInstantiation {
impl TryToRustTy for FunctionSig {
type Extra = Item;
- fn try_to_rust_ty(&self,
- ctx: &BindgenContext,
- item: &Item)
- -> error::Result<P<ast::Ty>> {
+ fn try_to_rust_ty(
+ &self,
+ ctx: &BindgenContext,
+ item: &Item,
+ ) -> error::Result<P<ast::Ty>> {
// TODO: we might want to consider ignoring the reference return value.
let ret = utils::fnsig_return_ty(ctx, &self);
let arguments = utils::fnsig_arguments(ctx, &self);
@@ -3001,8 +3133,12 @@ impl TryToRustTy for FunctionSig {
let abi = match self.abi() {
Abi::Known(abi) => abi,
Abi::Unknown(unknown_abi) => {
- panic!("Invalid or unknown abi {:?} for function {:?} {:?}",
- unknown_abi, item.canonical_name(ctx), self);
+ panic!(
+ "Invalid or unknown abi {:?} for function {:?} {:?}",
+ unknown_abi,
+ item.canonical_name(ctx),
+ self
+ );
}
};
@@ -3024,10 +3160,12 @@ impl TryToRustTy for FunctionSig {
impl CodeGenerator for Function {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
@@ -3100,8 +3238,12 @@ impl CodeGenerator for Function {
let abi = match signature.abi() {
Abi::Known(abi) => abi,
Abi::Unknown(unknown_abi) => {
- panic!("Invalid or unknown abi {:?} for function {:?} ({:?})",
- unknown_abi, canonical_name, self);
+ panic!(
+ "Invalid or unknown abi {:?} for function {:?} ({:?})",
+ unknown_abi,
+ canonical_name,
+ self
+ );
}
};
@@ -3114,11 +3256,12 @@ impl CodeGenerator for Function {
}
-fn objc_method_codegen(ctx: &BindgenContext,
- method: &ObjCMethod,
- class_name: Option<&str>,
- prefix: &str)
- -> (ast::ImplItem, ast::TraitItem) {
+fn objc_method_codegen(
+ ctx: &BindgenContext,
+ method: &ObjCMethod,
+ class_name: Option<&str>,
+ prefix: &str,
+) -> (ast::ImplItem, ast::TraitItem) {
let signature = method.signature();
let fn_args = utils::fnsig_arguments(ctx, signature);
let fn_ret = utils::fnsig_return_ty(ctx, signature);
@@ -3142,7 +3285,8 @@ fn objc_method_codegen(ctx: &BindgenContext,
};
// Collect the actual used argument names
- let arg_names: Vec<_> = fn_args.iter()
+ let arg_names: Vec<_> = fn_args
+ .iter()
.map(|ref arg| match arg.pat.node {
ast::PatKind::Ident(_, ref spanning, _) => {
spanning.node.name.as_str().to_string()
@@ -3157,9 +3301,9 @@ fn objc_method_codegen(ctx: &BindgenContext,
ctx.rust_ident(&method.format_method_call(&arg_names));
let body = if method.is_class_method() {
- let class_name =
- class_name.expect("Generating a class method without class name?")
- .to_owned();
+ let class_name = class_name
+ .expect("Generating a class method without class name?")
+ .to_owned();
let expect_msg = format!("Couldn't find {}", class_name);
quote_stmt!(ctx.ext_cx(),
msg_send![objc::runtime::Class::get($class_name).expect($expect_msg), $methods_and_args])
@@ -3202,10 +3346,12 @@ fn objc_method_codegen(ctx: &BindgenContext,
impl CodeGenerator for ObjCInterface {
type Extra = Item;
- fn codegen<'a>(&self,
- ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- item: &Item) {
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ item: &Item,
+ ) {
debug_assert!(item.is_enabled_for_codegen(ctx));
let mut impl_items = vec![];
@@ -3218,18 +3364,20 @@ impl CodeGenerator for ObjCInterface {
trait_items.push(trait_item)
}
- let instance_method_names : Vec<_> = self.methods().iter().map( { |m| m.rust_name() } ).collect();
+ let instance_method_names: Vec<_> =
+ self.methods().iter().map({ |m| m.rust_name() }).collect();
for class_method in self.class_methods() {
- let ambiquity = instance_method_names.contains(&class_method.rust_name());
- let prefix = if ambiquity {
- "class_"
- } else {
- ""
- };
- let (impl_item, trait_item) =
- objc_method_codegen(ctx, class_method, Some(self.name()), prefix);
+ let ambiquity =
+ instance_method_names.contains(&class_method.rust_name());
+ let prefix = if ambiquity { "class_" } else { "" };
+ let (impl_item, trait_item) = objc_method_codegen(
+ ctx,
+ class_method,
+ Some(self.name()),
+ prefix,
+ );
impl_items.push(impl_item);
trait_items.push(trait_item)
}
@@ -3289,7 +3437,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
}
mod utils {
- use super::{error, TryToRustTy, ToRustTyOrOpaque};
+ use super::{error, ToRustTyOrOpaque, TryToRustTy};
use aster;
use ir::context::{BindgenContext, ItemId};
use ir::function::FunctionSig;
@@ -3299,35 +3447,36 @@ mod utils {
use syntax::ast;
use syntax::ptr::P;
- pub fn prepend_objc_header(ctx: &BindgenContext,
- result: &mut Vec<P<ast::Item>>) {
+ pub fn prepend_objc_header(
+ ctx: &BindgenContext,
+ result: &mut Vec<P<ast::Item>>,
+ ) {
let use_objc = if ctx.options().objc_extern_crate {
quote_item!(ctx.ext_cx(),
#[macro_use]
extern crate objc;
- )
- .unwrap()
+ ).unwrap()
} else {
quote_item!(ctx.ext_cx(),
use objc;
- )
- .unwrap()
+ ).unwrap()
};
let id_type = quote_item!(ctx.ext_cx(),
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
- )
- .unwrap();
+ ).unwrap();
let items = vec![use_objc, id_type];
let old_items = mem::replace(result, items);
result.extend(old_items.into_iter());
}
- pub fn prepend_union_types(ctx: &BindgenContext,
- result: &mut Vec<P<ast::Item>>) {
+ pub fn prepend_union_types(
+ ctx: &BindgenContext,
+ result: &mut Vec<P<ast::Item>>,
+ ) {
let prefix = ctx.trait_prefix();
// TODO(emilio): The fmt::Debug impl could be way nicer with
@@ -3336,8 +3485,7 @@ mod utils {
#[repr(C)]
pub struct __BindgenUnionField<T>(
::$prefix::marker::PhantomData<T>);
- )
- .unwrap();
+ ).unwrap();
let union_field_impl = quote_item!(&ctx.ext_cx(),
impl<T> __BindgenUnionField<T> {
@@ -3356,8 +3504,7 @@ mod utils {
::$prefix::mem::transmute(self)
}
}
- )
- .unwrap();
+ ).unwrap();
let union_field_default_impl = quote_item!(&ctx.ext_cx(),
impl<T> ::$prefix::default::Default for __BindgenUnionField<T> {
@@ -3366,8 +3513,7 @@ mod utils {
Self::new()
}
}
- )
- .unwrap();
+ ).unwrap();
let union_field_clone_impl = quote_item!(&ctx.ext_cx(),
impl<T> ::$prefix::clone::Clone for __BindgenUnionField<T> {
@@ -3376,13 +3522,11 @@ mod utils {
Self::new()
}
}
- )
- .unwrap();
+ ).unwrap();
let union_field_copy_impl = quote_item!(&ctx.ext_cx(),
impl<T> ::$prefix::marker::Copy for __BindgenUnionField<T> {}
- )
- .unwrap();
+ ).unwrap();
let union_field_debug_impl = quote_item!(ctx.ext_cx(),
impl<T> ::$prefix::fmt::Debug for __BindgenUnionField<T> {
@@ -3391,8 +3535,7 @@ mod utils {
fmt.write_str("__BindgenUnionField")
}
}
- )
- .unwrap();
+ ).unwrap();
let items = vec![union_field_decl,
union_field_impl,
@@ -3405,8 +3548,10 @@ mod utils {
result.extend(old_items.into_iter());
}
- pub fn prepend_incomplete_array_types(ctx: &BindgenContext,
- result: &mut Vec<P<ast::Item>>) {
+ pub fn prepend_incomplete_array_types(
+ ctx: &BindgenContext,
+ result: &mut Vec<P<ast::Item>>,
+ ) {
let prefix = ctx.trait_prefix();
let incomplete_array_decl = quote_item!(ctx.ext_cx(),
@@ -3414,8 +3559,7 @@ mod utils {
#[derive(Default)]
pub struct __IncompleteArrayField<T>(
::$prefix::marker::PhantomData<T>);
- )
- .unwrap();
+ ).unwrap();
let incomplete_array_impl = quote_item!(&ctx.ext_cx(),
impl<T> __IncompleteArrayField<T> {
@@ -3444,8 +3588,7 @@ mod utils {
::$prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}
- )
- .unwrap();
+ ).unwrap();
let incomplete_array_debug_impl = quote_item!(ctx.ext_cx(),
impl<T> ::$prefix::fmt::Debug for __IncompleteArrayField<T> {
@@ -3454,8 +3597,7 @@ mod utils {
fmt.write_str("__IncompleteArrayField")
}
}
- )
- .unwrap();
+ ).unwrap();
let incomplete_array_clone_impl = quote_item!(&ctx.ext_cx(),
impl<T> ::$prefix::clone::Clone for __IncompleteArrayField<T> {
@@ -3464,13 +3606,11 @@ mod utils {
Self::new()
}
}
- )
- .unwrap();
+ ).unwrap();
let incomplete_array_copy_impl = quote_item!(&ctx.ext_cx(),
impl<T> ::$prefix::marker::Copy for __IncompleteArrayField<T> {}
- )
- .unwrap();
+ ).unwrap();
let items = vec![incomplete_array_decl,
incomplete_array_impl,
@@ -3482,8 +3622,10 @@ mod utils {
result.extend(old_items.into_iter());
}
- pub fn prepend_complex_type(ctx: &BindgenContext,
- result: &mut Vec<P<ast::Item>>) {
+ pub fn prepend_complex_type(
+ ctx: &BindgenContext,
+ result: &mut Vec<P<ast::Item>>,
+ ) {
let complex_type = quote_item!(ctx.ext_cx(),
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
#[repr(C)]
@@ -3491,31 +3633,35 @@ mod utils {
pub re: T,
pub im: T
}
- )
- .unwrap();
+ ).unwrap();
let items = vec![complex_type];
let old_items = mem::replace(result, items);
result.extend(old_items.into_iter());
}
- pub fn build_templated_path(item: &Item,
- ctx: &BindgenContext,
- template_params: Vec<ItemId>)
- -> error::Result<P<ast::Ty>> {
+ pub fn build_templated_path(
+ item: &Item,
+ ctx: &BindgenContext,
+ template_params: Vec<ItemId>,
+ ) -> error::Result<P<ast::Ty>> {
let path = item.namespace_aware_canonical_path(ctx);
let builder = aster::AstBuilder::new().ty().path();
- let template_params = template_params.iter()
+ let template_params = template_params
+ .iter()
.map(|param| param.try_to_rust_ty(ctx, &()))
.collect::<error::Result<Vec<_>>>()?;
// XXX: I suck at aster.
if path.len() == 1 {
- return Ok(builder.segment(&path[0])
- .with_tys(template_params)
- .build()
- .build());
+ return Ok(
+ builder
+ .segment(&path[0])
+ .with_tys(template_params)
+ .build()
+ .build(),
+ );
}
let mut builder = builder.id(&path[0]);
@@ -3523,7 +3669,8 @@ mod utils {
// Take into account the skip(1)
builder = if i == path.len() - 2 {
// XXX Extra clone courtesy of the borrow checker.
- builder.segment(&segment)
+ builder
+ .segment(&segment)
.with_tys(template_params.clone())
.build()
} else {
@@ -3539,10 +3686,11 @@ mod utils {
quote_ty!(ctx.ext_cx(), $ident)
}
- pub fn type_from_named(ctx: &BindgenContext,
- name: &str,
- _inner: ItemId)
- -> Option<P<ast::Ty>> {
+ pub fn type_from_named(
+ ctx: &BindgenContext,
+ name: &str,
+ _inner: ItemId,
+ ) -> Option<P<ast::Ty>> {
// FIXME: We could use the inner item to check this is really a
// primitive type but, who the heck overrides these anyway?
Some(match name {
@@ -3557,23 +3705,23 @@ mod utils {
"uintptr_t" | "size_t" => primitive_ty(ctx, "usize"),
- "intptr_t" | "ptrdiff_t" | "ssize_t" => {
- primitive_ty(ctx, "isize")
- }
+ "intptr_t" | "ptrdiff_t" | "ssize_t" => primitive_ty(ctx, "isize"),
_ => return None,
})
}
- pub fn rust_fndecl_from_signature(ctx: &BindgenContext,
- sig: &Item)
- -> P<ast::FnDecl> {
+ pub fn rust_fndecl_from_signature(
+ ctx: &BindgenContext,
+ sig: &Item,
+ ) -> P<ast::FnDecl> {
let signature = sig.kind().expect_type().canonical_type(ctx);
let signature = match *signature.kind() {
TypeKind::Function(ref sig) => sig,
_ => panic!("How?"),
};
- let decl_ty = signature.try_to_rust_ty(ctx, sig)
+ let decl_ty = signature
+ .try_to_rust_ty(ctx, sig)
.expect("function signature to Rust type conversion is infallible");
match decl_ty.unwrap().node {
ast::TyKind::BareFn(bare_fn) => bare_fn.unwrap().decl,
@@ -3581,9 +3729,10 @@ mod utils {
}
}
- pub fn fnsig_return_ty(ctx: &BindgenContext,
- sig: &FunctionSig)
- -> ast::FunctionRetTy {
+ pub fn fnsig_return_ty(
+ ctx: &BindgenContext,
+ sig: &FunctionSig,
+ ) -> ast::FunctionRetTy {
let return_item = ctx.resolve_item(sig.return_type());
if let TypeKind::Void = *return_item.kind().expect_type().kind() {
ast::FunctionRetTy::Default(ctx.span())
@@ -3592,9 +3741,10 @@ mod utils {
}
}
- pub fn fnsig_arguments(ctx: &BindgenContext,
- sig: &FunctionSig)
- -> Vec<ast::Arg> {
+ pub fn fnsig_arguments(
+ ctx: &BindgenContext,
+ sig: &FunctionSig,
+ ) -> Vec<ast::Arg> {
use super::ToPtr;
let mut unnamed_arguments = 0;
sig.argument_types().iter().map(|&(ref name, ty)| {
diff --git a/src/lib.rs b/src/lib.rs
index 3a853829..437de16e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,15 +4,12 @@
//! functions and use types defined in the header.
//!
//! See the [`Builder`](./struct.Builder.html) struct for usage.
-
#![deny(missing_docs)]
#![deny(warnings)]
#![deny(unused_extern_crates)]
-
// 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)]
@@ -86,14 +83,14 @@ use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;
use std::fs::{File, OpenOptions};
-use std::iter;
use std::io::{self, Write};
+use std::iter;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::Arc;
use syntax::ast;
-use syntax::codemap::{DUMMY_SP, Span};
+use syntax::codemap::{Span, DUMMY_SP};
use syntax::print::pp::eof;
use syntax::print::pprust;
use syntax::ptr::P;
@@ -179,7 +176,7 @@ pub fn builder() -> Builder {
}
impl Builder {
- /// Generates the command line flags use for creating `Builder`.
+ /// Generates the command line flags use for creating `Builder`.
pub fn command_line_flags(&self) -> Vec<String> {
let mut output_vector: Vec<String> = Vec::new();
@@ -193,9 +190,11 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--bitfield-enum".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--bitfield-enum".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
@@ -203,9 +202,11 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--constified-enum".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--constified-enum".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
@@ -213,9 +214,11 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--constified-enum-module".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--constified-enum-module".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
@@ -223,9 +226,11 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--blacklist-type".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--blacklist-type".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
if !self.options.layout_tests {
@@ -236,6 +241,10 @@ impl Builder {
output_vector.push("--no-derive-debug".into());
}
+ if !self.options.impl_debug {
+ output_vector.push("--force-derive-debug".into());
+ }
+
if !self.options.derive_default {
output_vector.push("--no-derive-default".into());
} else {
@@ -285,9 +294,11 @@ impl Builder {
.links
.iter()
.map(|&(ref item, _)| {
- output_vector.push("--framework".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--framework".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
if !self.options.codegen_config.functions {
@@ -297,7 +308,7 @@ impl Builder {
output_vector.push("--generate".into());
//Temporary placeholder for below 4 options
- let mut options:Vec<String> = Vec::new();
+ let mut options: Vec<String> = Vec::new();
if self.options.codegen_config.functions {
options.push("function".into());
}
@@ -327,9 +338,11 @@ impl Builder {
.links
.iter()
.map(|&(ref item, _)| {
- output_vector.push("--clang-args".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--clang-args".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
if !self.options.convert_floats {
@@ -349,27 +362,33 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--opaque-type".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--opaque-type".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
.raw_lines
.iter()
.map(|item| {
- output_vector.push("--raw-line".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--raw-line".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
.links
.iter()
.map(|&(ref item, _)| {
- output_vector.push("--static".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--static".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
if self.options.use_core {
@@ -385,9 +404,11 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--whitelist-function".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--whitelist-function".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
@@ -395,9 +416,11 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--whitelist-type".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--whitelist-type".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
self.options
@@ -405,24 +428,25 @@ impl Builder {
.get_items()
.iter()
.map(|item| {
- output_vector.push("--whitelist-var".into());
- output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
- })
+ output_vector.push("--whitelist-var".into());
+ output_vector.push(
+ item.trim_left_matches("^").trim_right_matches("$").into(),
+ );
+ })
.count();
output_vector.push("--".into());
if !self.options.clang_args.is_empty() {
- output_vector.extend(
- self.options
- .clang_args
- .iter()
- .cloned()
- );
+ output_vector.extend(self.options.clang_args.iter().cloned());
}
if self.input_headers.len() > 1 {
- output_vector.extend(self.input_headers[..self.input_headers.len() - 1].iter().cloned());
+ output_vector.extend(
+ self.input_headers[..self.input_headers.len() - 1]
+ .iter()
+ .cloned(),
+ );
}
output_vector
@@ -459,7 +483,8 @@ impl Builder {
///
/// The file `name` will be added to the clang arguments.
pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
- self.input_header_contents.push((name.into(), contents.into()));
+ self.input_header_contents
+ .push((name.into(), contents.into()));
self
}
@@ -595,8 +620,10 @@ impl Builder {
/// Add arguments to be passed straight through to clang.
pub fn clang_args<I>(mut self, iter: I) -> Builder
- where I: IntoIterator,
- I::Item: AsRef<str> {
+ where
+ I: IntoIterator,
+ I::Item: AsRef<str>,
+ {
for arg in iter {
self = self.clang_arg(arg.as_ref())
}
@@ -617,7 +644,9 @@ impl Builder {
/// Make the generated bindings link the given framework.
pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
- self.options.links.push((library.into(), LinkType::Framework));
+ self.options
+ .links
+ .push((library.into(), LinkType::Framework));
self
}
@@ -646,6 +675,12 @@ impl Builder {
self
}
+ /// Set whether `Debug` should be implemented, if it can not be derived automatically.
+ pub fn impl_debug(mut self, doit: bool) -> Self {
+ self.options.impl_debug = doit;
+ self
+ }
+
/// Set whether `Default` should be derived by default.
pub fn derive_default(mut self, doit: bool) -> Self {
self.options.derive_default = doit;
@@ -763,7 +798,10 @@ impl Builder {
/// Allows configuring types in different situations, see the
/// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
- pub fn parse_callbacks(mut self, cb: Box<callbacks::ParseCallbacks>) -> Self {
+ pub fn parse_callbacks(
+ mut self,
+ cb: Box<callbacks::ParseCallbacks>,
+ ) -> Self {
self.options.parse_callbacks = Some(cb);
self
}
@@ -785,18 +823,17 @@ impl Builder {
pub fn generate<'ctx>(mut self) -> Result<Bindings<'ctx>, ()> {
self.options.input_header = self.input_headers.pop();
self.options.clang_args.extend(
- self.input_headers
- .drain(..)
- .flat_map(|header| {
- iter::once("-include".into())
- .chain(iter::once(header))
- })
+ self.input_headers.drain(..).flat_map(|header| {
+ iter::once("-include".into()).chain(iter::once(header))
+ }),
);
self.options.input_unsaved_files.extend(
self.input_header_contents
.drain(..)
- .map(|(name, contents)| clang::UnsavedFile::new(&name, &contents))
+ .map(|(name, contents)| {
+ clang::UnsavedFile::new(&name, &contents)
+ }),
);
Bindings::generate(self.options, None)
@@ -809,8 +846,12 @@ impl Builder {
/// `__bindgen.ii`
pub fn dump_preprocessed_input(&self) -> io::Result<()> {
let clang = clang_sys::support::Clang::find(None, &[])
- .ok_or_else(|| io::Error::new(io::ErrorKind::Other,
- "Cannot find clang executable"))?;
+ .ok_or_else(|| {
+ io::Error::new(
+ io::ErrorKind::Other,
+ "Cannot find clang executable",
+ )
+ })?;
// The contents of a wrapper file that includes all the input header
// files.
@@ -879,8 +920,10 @@ impl Builder {
if child.wait()?.success() {
Ok(())
} else {
- Err(io::Error::new(io::ErrorKind::Other,
- "clang exited with non-zero status"))
+ Err(io::Error::new(
+ io::ErrorKind::Other,
+ "clang exited with non-zero status",
+ ))
}
}
}
@@ -951,6 +994,10 @@ pub struct BindgenOptions {
/// and types.
pub derive_debug: bool,
+ /// True if we should implement the Debug trait for C/C++ structures and types
+ /// that do not support automatically deriving Debug.
+ pub impl_debug: bool,
+
/// True if we should derive Default trait implementations for C/C++ structures
/// and types.
pub derive_default: bool,
@@ -1063,6 +1110,7 @@ impl Default for BindgenOptions {
emit_ir_graphviz: None,
layout_tests: true,
derive_debug: true,
+ impl_debug: false,
derive_default: false,
enable_cxx_namespaces: false,
disable_name_namespacing: false,
@@ -1135,9 +1183,10 @@ impl<'ctx> Bindings<'ctx> {
///
/// Deprecated - use a `Builder` instead
#[deprecated]
- pub fn generate(mut options: BindgenOptions,
- span: Option<Span>)
- -> Result<Bindings<'ctx>, ()> {
+ pub fn generate(
+ mut options: BindgenOptions,
+ span: Option<Span>,
+ ) -> Result<Bindings<'ctx>, ()> {
let span = span.unwrap_or(DUMMY_SP);
ensure_libclang_is_loaded();
@@ -1171,10 +1220,13 @@ impl<'ctx> Bindings<'ctx> {
};
// TODO: Make this path fixup configurable?
- if let Some(clang) = clang_sys::support::Clang::find(None, &clang_args_for_clang_sys) {
+ if let Some(clang) =
+ clang_sys::support::Clang::find(None, &clang_args_for_clang_sys)
+ {
// If --target is specified, assume caller knows what they're doing
// and don't mess with include paths for them
- let has_target_arg = options.clang_args
+ let has_target_arg = options
+ .clang_args
.iter()
.rposition(|arg| arg.starts_with("--target"))
.is_some();
@@ -1224,25 +1276,29 @@ impl<'ctx> Bindings<'ctx> {
let mut mod_str = vec![];
{
let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
- self.write(ref_writer).expect("Could not write bindings to string");
+ self.write(ref_writer)
+ .expect("Could not write bindings to string");
}
String::from_utf8(mod_str).unwrap()
}
/// Write these bindings as source text to a file.
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
- let file = try!(OpenOptions::new()
- .write(true)
- .truncate(true)
- .create(true)
- .open(path));
+ 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.
pub fn write<'a>(&self, mut writer: Box<Write + 'a>) -> io::Result<()> {
- try!(writer.write("/* automatically generated by rust-bindgen */\n\n"
- .as_bytes()));
+ try!(writer.write(
+ "/* automatically generated by rust-bindgen */\n\n".as_bytes(),
+ ));
for line in self.context.options().raw_lines.iter() {
try!(writer.write(line.as_bytes()));
@@ -1267,10 +1323,11 @@ 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<ItemId>)
- -> clang_sys::CXChildVisitResult {
+pub fn parse_one(
+ ctx: &mut BindgenContext,
+ cursor: clang::Cursor,
+ parent: Option<ItemId>,
+) -> clang_sys::CXChildVisitResult {
if !filter_builtins(ctx, &cursor) {
return CXChildVisit_Continue;
}
@@ -1321,8 +1378,10 @@ fn parse(context: &mut BindgenContext) -> Result<(), ()> {
cursor.visit(|cursor| parse_one(context, cursor, None))
});
- assert!(context.current_module() == context.root_module(),
- "How did this happen?");
+ assert!(
+ context.current_module() == context.root_module(),
+ "How did this happen?"
+ );
Ok(())
}
@@ -1343,25 +1402,24 @@ pub fn clang_version() -> ClangVersion {
}
let raw_v: String = clang::extract_clang_version();
- let split_v: Option<Vec<&str>> = raw_v.split_whitespace()
+ let split_v: Option<Vec<&str>> = raw_v
+ .split_whitespace()
.nth(2)
.map(|v| v.split('.').collect());
match split_v {
- Some(v) => {
- if v.len() >= 2 {
- let maybe_major = v[0].parse::<u32>();
- let maybe_minor = v[1].parse::<u32>();
- match (maybe_major, maybe_minor) {
- (Ok(major), Ok(minor)) => {
- return ClangVersion {
- parsed: Some((major, minor)),
- full: raw_v.clone(),
- }
+ Some(v) => if v.len() >= 2 {
+ let maybe_major = v[0].parse::<u32>();
+ let maybe_minor = v[1].parse::<u32>();
+ match (maybe_major, maybe_minor) {
+ (Ok(major), Ok(minor)) => {
+ return ClangVersion {
+ parsed: Some((major, minor)),
+ full: raw_v.clone(),
}
- _ => {}
}
+ _ => {}
}
- }
+ },
None => {}
};
ClangVersion {
@@ -1377,30 +1435,45 @@ fn commandline_flag_unit_test_function() {
let bindings = ::builder();
let command_line_flags = bindings.command_line_flags();
- let test_cases = vec!["--no-derive-default",
- "--generate", "function,types,vars,methods,constructors,destructors"]
- .iter()
- .map(|&x| x.into())
- .collect::<Vec<String>>();
+ let test_cases = vec![
+ "--no-derive-default",
+ "--generate",
+ "function,types,vars,methods,constructors,destructors",
+ ].iter()
+ .map(|&x| x.into())
+ .collect::<Vec<String>>();
- assert!(test_cases.iter().all(|ref x| command_line_flags.contains(x)) );
+ assert!(
+ test_cases
+ .iter()
+ .all(|ref x| command_line_flags.contains(x),)
+ );
//Test 2
- let bindings = ::builder().header("input_header")
- .whitelisted_type("Distinct_Type")
- .whitelisted_function("safe_function");
+ let bindings = ::builder()
+ .header("input_header")
+ .whitelisted_type("Distinct_Type")
+ .whitelisted_function("safe_function");
let command_line_flags = bindings.command_line_flags();
- let test_cases = vec!["input_header",
- "--no-derive-default",
- "--generate", "function,types,vars,methods,constructors,destructors",
- "--whitelist-type", "Distinct_Type",
- "--whitelist-function", "safe_function"]
- .iter()
- .map(|&x| x.into())
- .collect::<Vec<String>>();
+ let test_cases = vec![
+ "input_header",
+ "--no-derive-default",
+ "--generate",
+ "function,types,vars,methods,constructors,destructors",
+ "--whitelist-type",
+ "Distinct_Type",
+ "--whitelist-function",
+ "safe_function",
+ ].iter()
+ .map(|&x| x.into())
+ .collect::<Vec<String>>();
println!("{:?}", command_line_flags);
- assert!(test_cases.iter().all(|ref x| command_line_flags.contains(x)) );
+ assert!(
+ test_cases
+ .iter()
+ .all(|ref x| command_line_flags.contains(x),)
+ );
}
diff --git a/src/options.rs b/src/options.rs
index f2ed5494..b122f39d 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -1,13 +1,14 @@
-use bindgen::{Builder, CodegenConfig, builder};
+use bindgen::{builder, Builder, CodegenConfig};
use clap::{App, Arg};
use std::fs::File;
use std::io::{self, Error, ErrorKind};
/// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
-pub fn builder_from_flags<I>
- (args: I)
- -> Result<(Builder, Box<io::Write>, bool), io::Error>
- where I: Iterator<Item = String>,
+pub fn builder_from_flags<I>(
+ args: I,
+) -> Result<(Builder, Box<io::Write>, bool), io::Error>
+where
+ I: Iterator<Item = String>,
{
let matches = App::new("bindgen")
.version(env!("CARGO_PKG_VERSION"))
@@ -55,6 +56,9 @@ pub fn builder_from_flags<I>
Arg::with_name("no-derive-debug")
.long("no-derive-debug")
.help("Avoid deriving Debug on any type."),
+ Arg::with_name("force-derive-debug")
+ .long("force-derive-debug")
+ .help("Create Debug implementation, if it can not be derived automatically."),
Arg::with_name("no-derive-default")
.long("no-derive-default")
.hidden(true)
@@ -261,6 +265,10 @@ pub fn builder_from_flags<I>
builder = builder.derive_debug(false);
}
+ if matches.is_present("force-derive-debug") {
+ builder = builder.impl_debug(true);
+ }
+
if matches.is_present("with-derive-default") {
builder = builder.derive_default(true);
}
@@ -294,9 +302,10 @@ pub fn builder_from_flags<I>
"constructors" => config.constructors = true,
"destructors" => config.destructors = true,
otherwise => {
- return Err(Error::new(ErrorKind::Other,
- format!("Unknown generate item: {}",
- otherwise)));
+ return Err(Error::new(
+ ErrorKind::Other,
+ format!("Unknown generate item: {}", otherwise),
+ ));
}
}
}
diff --git a/tests/expectations/tests/derive-debug-bitfield.rs b/tests/expectations/tests/derive-debug-bitfield.rs
new file mode 100644
index 00000000..62e941e4
--- /dev/null
+++ b/tests/expectations/tests/derive-debug-bitfield.rs
@@ -0,0 +1,119 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub struct C {
+ pub _bitfield_1: u8,
+ pub large_array: [::std::os::raw::c_int; 50usize],
+}
+#[test]
+fn bindgen_test_layout_C() {
+ assert_eq!(::std::mem::size_of::<C>() , 204usize , concat ! (
+ "Size of: " , stringify ! ( C ) ));
+ assert_eq! (::std::mem::align_of::<C>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( C ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const C ) ) . large_array as * const _ as usize
+ } , 4usize , concat ! (
+ "Alignment of field: " , stringify ! ( C ) , "::" , stringify
+ ! ( large_array ) ));
+}
+impl Clone for C {
+ fn clone(&self) -> Self { *self }
+}
+impl Default for C {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl ::std::fmt::Debug for C {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "C {{ a : {:?}, b : {:?}, large_array: [{}] }}" , self . a
+ ( ) , self . b ( ) , self . large_array . iter ( ) .
+ enumerate ( ) . map (
+ | ( i , v ) | format ! (
+ "{}{:?}" , if i > 0 { ", " } else { "" } , v ) ) . collect :: <
+ String > ( ))
+ }
+}
+impl C {
+ #[inline]
+ pub fn a(&self) -> bool {
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ as
+ *const u8,
+ &mut unit_field_val as *mut u8 as
+ *mut u8,
+ ::std::mem::size_of::<u8>())
+ };
+ let mask = 1u64 as u8;
+ let val = (unit_field_val & mask) >> 0usize;
+ unsafe { ::std::mem::transmute(val as u8) }
+ }
+ #[inline]
+ pub fn set_a(&mut self, val: bool) {
+ let mask = 1u64 as u8;
+ let val = val as u8 as u8;
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ as
+ *const u8,
+ &mut unit_field_val as *mut u8 as
+ *mut u8,
+ ::std::mem::size_of::<u8>())
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 0usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as
+ *const u8,
+ &mut self._bitfield_1 as *mut _ as
+ *mut u8,
+ ::std::mem::size_of::<u8>());
+ }
+ }
+ #[inline]
+ pub fn b(&self) -> bool {
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ as
+ *const u8,
+ &mut unit_field_val as *mut u8 as
+ *mut u8,
+ ::std::mem::size_of::<u8>())
+ };
+ let mask = 254u64 as u8;
+ let val = (unit_field_val & mask) >> 1usize;
+ unsafe { ::std::mem::transmute(val as u8) }
+ }
+ #[inline]
+ pub fn set_b(&mut self, val: bool) {
+ let mask = 254u64 as u8;
+ let val = val as u8 as u8;
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ as
+ *const u8,
+ &mut unit_field_val as *mut u8 as
+ *mut u8,
+ ::std::mem::size_of::<u8>())
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 1usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as
+ *const u8,
+ &mut self._bitfield_1 as *mut _ as
+ *mut u8,
+ ::std::mem::size_of::<u8>());
+ }
+ }
+ #[inline]
+ pub fn new_bitfield_1(a: bool, b: bool) -> u8 {
+ ({ ({ 0 } | ((a as u8 as u8) << 0usize) & (1u64 as u8)) } |
+ ((b as u8 as u8) << 1usize) & (254u64 as u8))
+ }
+}
diff --git a/tests/expectations/tests/derive-debug-function-pointer.rs b/tests/expectations/tests/derive-debug-function-pointer.rs
new file mode 100644
index 00000000..03cafe97
--- /dev/null
+++ b/tests/expectations/tests/derive-debug-function-pointer.rs
@@ -0,0 +1,47 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub struct Nice {
+ pub pointer: Nice_Function,
+ pub large_array: [::std::os::raw::c_int; 34usize],
+}
+pub type Nice_Function =
+ ::std::option::Option<unsafe extern "C" fn(data: ::std::os::raw::c_int)>;
+#[test]
+fn bindgen_test_layout_Nice() {
+ assert_eq!(::std::mem::size_of::<Nice>() , 144usize , concat ! (
+ "Size of: " , stringify ! ( Nice ) ));
+ assert_eq! (::std::mem::align_of::<Nice>() , 8usize , concat ! (
+ "Alignment of " , stringify ! ( Nice ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const Nice ) ) . pointer as * const _ as usize
+ } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( Nice ) , "::" ,
+ stringify ! ( pointer ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const Nice ) ) . large_array as * const _ as
+ usize } , 8usize , concat ! (
+ "Alignment of field: " , stringify ! ( Nice ) , "::" ,
+ stringify ! ( large_array ) ));
+}
+impl Clone for Nice {
+ fn clone(&self) -> Self { *self }
+}
+impl Default for Nice {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl ::std::fmt::Debug for Nice {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "Nice {{ pointer: {:?}, large_array: [{}] }}" , self .
+ pointer , self . large_array . iter ( ) . enumerate ( ) . map
+ (
+ | ( i , v ) | format ! (
+ "{}{:?}" , if i > 0 { ", " } else { "" } , v ) ) . collect :: <
+ String > ( ))
+ }
+}
diff --git a/tests/expectations/tests/derive-debug-generic.rs b/tests/expectations/tests/derive-debug-generic.rs
new file mode 100644
index 00000000..f238234a
--- /dev/null
+++ b/tests/expectations/tests/derive-debug-generic.rs
@@ -0,0 +1,19 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+pub struct Generic<T> {
+ pub t: [T; 40usize],
+ pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl <T> Default for Generic<T> {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl <T> ::std::fmt::Debug for Generic<T> {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "Generic {{ t: Array with length 40 }}")
+ }
+}
diff --git a/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs b/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs
new file mode 100644
index 00000000..e5529255
--- /dev/null
+++ b/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs
@@ -0,0 +1,30 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+pub struct Instance {
+ pub val: [u32; 50usize],
+}
+#[test]
+fn bindgen_test_layout_Instance() {
+ assert_eq!(::std::mem::size_of::<Instance>() , 200usize , concat ! (
+ "Size of: " , stringify ! ( Instance ) ));
+ assert_eq! (::std::mem::align_of::<Instance>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( Instance ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const Instance ) ) . val as * const _ as usize
+ } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( Instance ) , "::" ,
+ stringify ! ( val ) ));
+}
+impl Default for Instance {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl ::std::fmt::Debug for Instance {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "Instance {{ val: opaque }}")
+ }
+}
diff --git a/tests/expectations/tests/derive-debug-opaque.rs b/tests/expectations/tests/derive-debug-opaque.rs
new file mode 100644
index 00000000..267aca11
--- /dev/null
+++ b/tests/expectations/tests/derive-debug-opaque.rs
@@ -0,0 +1,49 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+pub struct Opaque {
+ pub _bindgen_opaque_blob: [u32; 41usize],
+}
+#[test]
+fn bindgen_test_layout_Opaque() {
+ assert_eq!(::std::mem::size_of::<Opaque>() , 164usize , concat ! (
+ "Size of: " , stringify ! ( Opaque ) ));
+ assert_eq! (::std::mem::align_of::<Opaque>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( Opaque ) ));
+}
+impl Default for Opaque {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl ::std::fmt::Debug for Opaque {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "Opaque {{ opaque }}")
+ }
+}
+#[repr(C)]
+pub struct OpaqueUser {
+ pub opaque: Opaque,
+}
+#[test]
+fn bindgen_test_layout_OpaqueUser() {
+ assert_eq!(::std::mem::size_of::<OpaqueUser>() , 164usize , concat ! (
+ "Size of: " , stringify ! ( OpaqueUser ) ));
+ assert_eq! (::std::mem::align_of::<OpaqueUser>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( OpaqueUser ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const OpaqueUser ) ) . opaque as * const _ as
+ usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( OpaqueUser ) , "::" ,
+ stringify ! ( opaque ) ));
+}
+impl Default for OpaqueUser {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl ::std::fmt::Debug for OpaqueUser {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "OpaqueUser {{ opaque: {:?} }}" , self . opaque)
+ }
+}
diff --git a/tests/headers/derive-debug-bitfield.hpp b/tests/headers/derive-debug-bitfield.hpp
new file mode 100644
index 00000000..4d8c3771
--- /dev/null
+++ b/tests/headers/derive-debug-bitfield.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --opaque-type "Opaque" --force-derive-debug
+
+class C {
+ bool a: 1;
+ bool b: 7;
+ int large_array[50];
+};
diff --git a/tests/headers/derive-debug-function-pointer.hpp b/tests/headers/derive-debug-function-pointer.hpp
new file mode 100644
index 00000000..df746da5
--- /dev/null
+++ b/tests/headers/derive-debug-function-pointer.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --force-derive-debug
+
+class Nice {
+ typedef void (*Function) (int data);
+ Function pointer;
+ int large_array[34];
+};
diff --git a/tests/headers/derive-debug-generic.hpp b/tests/headers/derive-debug-generic.hpp
new file mode 100644
index 00000000..58afac45
--- /dev/null
+++ b/tests/headers/derive-debug-generic.hpp
@@ -0,0 +1,6 @@
+// bindgen-flags: --force-derive-debug
+
+template<typename T>
+class Generic {
+ T t[40];
+};
diff --git a/tests/headers/derive-debug-opaque-template-instantiation.hpp b/tests/headers/derive-debug-opaque-template-instantiation.hpp
new file mode 100644
index 00000000..555ba826
--- /dev/null
+++ b/tests/headers/derive-debug-opaque-template-instantiation.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --force-derive-debug
+
+template<typename T, int N>
+class Opaque {
+ T array[N];
+};
+
+class Instance {
+ Opaque<int, 50> val;
+};
diff --git a/tests/headers/derive-debug-opaque.hpp b/tests/headers/derive-debug-opaque.hpp
new file mode 100644
index 00000000..05c504a9
--- /dev/null
+++ b/tests/headers/derive-debug-opaque.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --opaque-type "Opaque" --force-derive-debug
+
+class Opaque {
+ int i;
+ int not_debug[40];
+};
+
+class OpaqueUser {
+ Opaque opaque;
+};