diff --git a/libbindgen/src/clang.rs b/libbindgen/src/clang.rs index 192ce09dbc..fc5575b38c 100644 --- a/libbindgen/src/clang.rs +++ b/libbindgen/src/clang.rs @@ -351,7 +351,7 @@ impl Cursor { /// Is the referent an inlined function? pub fn is_inlined_function(&self) -> bool { clang_Cursor_isFunctionInlined::is_loaded() && - unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } + unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } } /// Get the width of this cursor's referent bit field, or `None` if the @@ -404,7 +404,7 @@ impl Cursor { /// being aliased. pub fn typedef_type(&self) -> Option { let inner = Type { - x: unsafe { clang_getTypedefDeclUnderlyingType(self.x) } + x: unsafe { clang_getTypedefDeclUnderlyingType(self.x) }, }; if inner.is_valid() { Some(inner) } else { None } @@ -603,9 +603,7 @@ impl Type { /// Get a raw display name for this type. pub fn spelling(&self) -> String { - unsafe { - cxstring_into_string(clang_getTypeSpelling(self.x)) - } + unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) } } /// Is this type const qualified? @@ -879,9 +877,7 @@ impl Comment { /// Given that this comment is the start or end of an HTML tag, get its tag /// name. pub fn get_tag_name(&self) -> String { - unsafe { - cxstring_into_string(clang_HTMLTagComment_getTagName(self.x)) - } + unsafe { cxstring_into_string(clang_HTMLTagComment_getTagName(self.x)) } } /// Given that this comment is an HTML start tag, get its attributes. @@ -964,9 +960,7 @@ impl File { if self.x.is_null() { return None; } - Some(unsafe { - cxstring_into_string(clang_getFileName(self.x)) - }) + Some(unsafe { cxstring_into_string(clang_getFileName(self.x)) }) } } @@ -1117,8 +1111,8 @@ impl TranslationUnit { num_tokens as usize); for &token in token_array.iter() { let kind = clang_getTokenKind(token); - let spelling = cxstring_into_string( - clang_getTokenSpelling(self.x, token)); + let spelling = + cxstring_into_string(clang_getTokenSpelling(self.x, token)); tokens.push(Token { kind: kind, @@ -1175,7 +1169,9 @@ impl TranslationUnit { // NB: cexpr is not too happy about comments inside // expressions, so we strip them down here. CXToken_Comment => return None, - _ => panic!("Found unexpected token kind: {:?}", token.kind), + _ => { + panic!("Found unexpected token kind: {:?}", token.kind) + } }; Some(token::Token { @@ -1207,8 +1203,8 @@ impl Diagnostic { pub fn format(&self) -> String { unsafe { let opts = clang_defaultDiagnosticDisplayOptions(); - cxstring_into_string( - clang_formatDiagnostic(self.x, opts)) } + cxstring_into_string(clang_formatDiagnostic(self.x, opts)) + } } /// What is the severity of this diagnostic message? @@ -1312,7 +1308,8 @@ impl EvalResult { // `CXType_Unexposed` from evaluation. let mut found_cant_eval = false; cursor.visit(|c| { - if c.kind() == CXCursor_TypeRef && c.cur_type().kind() == CXType_Unexposed { + if c.kind() == CXCursor_TypeRef && + c.cur_type().kind() == CXType_Unexposed { found_cant_eval = true; CXChildVisit_Break } else { diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 2f18036a92..9734a520cc 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -39,8 +39,7 @@ fn root_import(ctx: &BindgenContext, module: &Item) -> P { let root_ident = ctx.rust_ident(&root); let super_ = aster::AstBuilder::new().id("super"); - let supers = module - .ancestors(ctx) + let supers = module.ancestors(ctx) .filter(|id| ctx.resolve_item(*id).is_module()) .map(|_| super_.clone()) .chain(iter::once(super_)); @@ -309,7 +308,8 @@ impl CodeGenerator for Module { item: &Item) { debug!("::codegen: item = {:?}", item); - let codegen_self = |result: &mut CodegenResult, found_any: &mut bool| { + let codegen_self = |result: &mut CodegenResult, + found_any: &mut bool| { for child in self.children() { if whitelisted_items.contains(child) { *found_any = true; @@ -742,7 +742,8 @@ impl CodeGenerator for CompInfo { fn $fn_name() { assert_eq!($size_of_expr, $size); assert_eq!($align_of_expr, $align); - }).unwrap(); + }) + .unwrap(); result.push(item); } return; @@ -1196,7 +1197,10 @@ impl CodeGenerator for CompInfo { if ctx.options().codegen_config.constructors { for sig in self.constructors() { - Method::new(MethodKind::Constructor, *sig, /* const */ false) + Method::new(MethodKind::Constructor, + *sig, + /* const */ + false) .codegen_method(ctx, &mut methods, &mut method_names, @@ -1342,7 +1346,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 { @@ -1353,8 +1358,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![]; @@ -1661,7 +1666,8 @@ impl CodeGenerator for Enum { 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() { + let mangled_name = if is_toplevel || + enum_ty.name().is_some() { variant_name } else { let parent_name = parent_canonical_name.as_ref() @@ -1762,7 +1768,9 @@ impl ToRustTy for Type { TypeKind::Void => raw_type(ctx, "c_void"), // TODO: we should do something smart with nullptr, or maybe *const // c_void is enough? - TypeKind::NullPtr => raw_type(ctx, "c_void").to_ptr(true, ctx.span()), + TypeKind::NullPtr => { + raw_type(ctx, "c_void").to_ptr(true, ctx.span()) + } TypeKind::Int(ik) => { match ik { IntKind::Bool => aster::ty::TyBuilder::new().bool(), diff --git a/libbindgen/src/ir/annotations.rs b/libbindgen/src/ir/annotations.rs index 968e2da187..3598c78cd2 100644 --- a/libbindgen/src/ir/annotations.rs +++ b/libbindgen/src/ir/annotations.rs @@ -139,11 +139,11 @@ impl Annotations { "hide" => self.hide = true, "nocopy" => self.disallow_copy = true, "replaces" => { - self.use_instead_of = - Some(attr.value.split("::") - .map(Into::into) - .collect()) - }, + self.use_instead_of = Some(attr.value + .split("::") + .map(Into::into) + .collect()) + } "private" => { self.private_fields = Some(attr.value != "false") } diff --git a/libbindgen/src/ir/comp.rs b/libbindgen/src/ir/comp.rs index 66937b0c44..d5d3426245 100644 --- a/libbindgen/src/ir/comp.rs +++ b/libbindgen/src/ir/comp.rs @@ -533,11 +533,7 @@ impl CompInfo { warn!("warning: Template parameter is not a type"); } - if specialization { - args - } else { - vec![] - } + if specialization { args } else { vec![] } } }; @@ -717,16 +713,15 @@ impl CompInfo { // NB: This gets us an owned `Function`, not a // `FunctionSig`. - let signature = - Item::parse(cur, Some(potential_id), ctx) - .expect("CXXMethod"); + let signature = Item::parse(cur, Some(potential_id), ctx) + .expect("CXXMethod"); match cur.kind() { CXCursor_Constructor => { ci.constructors.push(signature); } // TODO(emilio): Bind the destructor? - CXCursor_Destructor => {}, + CXCursor_Destructor => {} CXCursor_CXXMethod => { let is_const = cur.method_is_const(); let method_kind = if is_static { @@ -737,9 +732,8 @@ impl CompInfo { MethodKind::Normal }; - let method = Method::new(method_kind, - signature, - is_const); + let method = + Method::new(method_kind, signature, is_const); ci.methods.push(method); } diff --git a/libbindgen/src/ir/enum_ty.rs b/libbindgen/src/ir/enum_ty.rs index dc6a866519..d7e4de099b 100644 --- a/libbindgen/src/ir/enum_ty.rs +++ b/libbindgen/src/ir/enum_ty.rs @@ -49,9 +49,8 @@ impl Enum { } let declaration = ty.declaration().canonical(); - let repr = declaration.enum_type().and_then(|et| { - Item::from_ty(&et, None, None, ctx).ok() - }); + let repr = declaration.enum_type() + .and_then(|et| Item::from_ty(&et, None, None, ctx).ok()); let mut variants = vec![]; let is_signed = match repr { diff --git a/libbindgen/src/ir/function.rs b/libbindgen/src/ir/function.rs index 516c486e86..7aed3d7ebf 100644 --- a/libbindgen/src/ir/function.rs +++ b/libbindgen/src/ir/function.rs @@ -188,7 +188,7 @@ impl FunctionSig { let is_method = cursor.kind() == CXCursor_CXXMethod; let is_constructor = cursor.kind() == CXCursor_Constructor; if (is_constructor || is_method) && - cursor.lexical_parent() != cursor.semantic_parent() { + cursor.lexical_parent() != cursor.semantic_parent() { // Only parse constructors once. return Err(ParseError::Continue); } diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs index 00c2982209..b330291924 100644 --- a/libbindgen/src/ir/item.rs +++ b/libbindgen/src/ir/item.rs @@ -91,8 +91,8 @@ pub struct ItemAncestorsIter<'a, 'b> seen: DebugOnlyItemSet, } -impl <'a, 'b> ItemAncestorsIter<'a, 'b> - where 'b: 'a +impl<'a, 'b> ItemAncestorsIter<'a, 'b> + where 'b: 'a, { fn new(ctx: &'a BindgenContext<'b>, item: ItemId) -> Self { ItemAncestorsIter { @@ -606,9 +606,7 @@ impl Item { } /// Get the target item id for name generation. - fn name_target(&self, - ctx: &BindgenContext) - -> ItemId { + fn name_target(&self, ctx: &BindgenContext) -> ItemId { let mut targets_seen = DebugOnlyItemSet::new(); let mut item = self; @@ -673,7 +671,7 @@ impl Item { func.name() == func_name }) .position(|m| m.signature() == self.id()) - }) + }); } } @@ -682,9 +680,7 @@ impl Item { } /// Get this item's base name (aka non-namespaced name). - fn base_name(&self, - ctx: &BindgenContext) - -> String { + fn base_name(&self, ctx: &BindgenContext) -> String { if let Some(path) = self.annotations().use_instead_of() { return path.last().unwrap().clone(); } @@ -737,8 +733,7 @@ impl Item { ctx: &BindgenContext, opt: &NameOptions) -> String { - let target = - ctx.resolve_item(self.name_target(ctx)); + let target = ctx.resolve_item(self.name_target(ctx)); // Short-circuit if the target has an override, and just use that. if let Some(path) = target.annotations.use_instead_of() { @@ -1080,7 +1075,7 @@ impl ClangItemParser for Item { } if let Some(ty) = - ctx.builtin_or_resolved_ty(id, parent_id, ty, location) { + ctx.builtin_or_resolved_ty(id, parent_id, ty, location) { return Ok(ty); } @@ -1098,10 +1093,9 @@ impl ClangItemParser for Item { }; if valid_decl { - if let Some(&(_, item_id)) = - ctx.currently_parsed_types - .iter() - .find(|&&(d, _)| d == declaration_to_look_for) { + if let Some(&(_, item_id)) = ctx.currently_parsed_types + .iter() + .find(|&&(d, _)| d == declaration_to_look_for) { debug!("Avoiding recursion parsing type: {:?}", ty); return Ok(item_id); } @@ -1272,9 +1266,9 @@ impl ItemCanonicalPath for Item { .filter(|item| item.is_module() || item.id() == target.id()) .map(|item| { ctx.resolve_item(item.name_target(ctx)) - .name(ctx) - .within_namespaces() - .get() + .name(ctx) + .within_namespaces() + .get() }) .collect(); path.reverse(); diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs index ada3d9b1bc..1878471dc2 100644 --- a/libbindgen/src/ir/ty.rs +++ b/libbindgen/src/ir/ty.rs @@ -660,12 +660,13 @@ impl Type { name = current.spelling(); - let inner_ty = cur.typedef_type().expect("Not valid Type?"); - inner = Item::from_ty( - &inner_ty, - Some(cur), - Some(potential_id), - ctx); + let inner_ty = cur.typedef_type() + .expect("Not valid Type?"); + inner = + Item::from_ty(&inner_ty, + Some(cur), + Some(potential_id), + ctx); } CXCursor_TemplateTypeParameter => { // See the comment in src/ir/comp.rs @@ -701,7 +702,9 @@ impl Type { } }; - TypeKind::TemplateAlias(name.clone(), inner_type, args) + TypeKind::TemplateAlias(name.clone(), + inner_type, + args) } CXCursor_TemplateRef => { let referenced = location.referenced().unwrap(); @@ -709,9 +712,9 @@ impl Type { debug!("TemplateRef: location = {:?}; referenced = \ {:?}; referenced_ty = {:?}", - location, - referenced, - referenced_ty); + location, + referenced, + referenced_ty); return Self::from_clang_ty(potential_id, &referenced_ty, @@ -726,9 +729,9 @@ impl Type { debug!("TypeRef: location = {:?}; referenced = \ {:?}; referenced_ty = {:?}", - location, - referenced, - referenced_ty); + location, + referenced, + referenced_ty); let item = Item::from_ty_or_ref_with_id(potential_id, diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs index 4ef8b54ca9..473dcf2997 100644 --- a/libbindgen/src/lib.rs +++ b/libbindgen/src/lib.rs @@ -87,6 +87,7 @@ use std::collections::HashSet; use std::fs::OpenOptions; use std::io::{self, Write}; use std::path::Path; +use std::sync::{Arc, Mutex}; use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; @@ -495,6 +496,34 @@ pub enum LinkType { Framework, } +fn ensure_libclang_is_loaded() { + if clang_sys::is_loaded() { + return; + } + + // XXX (issue #350): Ensure that our dynamically loaded `libclang` + // doesn't get dropped prematurely, nor is loaded multiple times + // across different threads. + + lazy_static! { + static ref LIBCLANG: Mutex>> = { + Mutex::new(None) + }; + } + + let mut libclang = LIBCLANG.lock().unwrap(); + if !clang_sys::is_loaded() { + if libclang.is_none() { + // TODO(emilio): Return meaningful error (breaking). + clang_sys::load().expect("Unable to find libclang"); + *libclang = Some(clang_sys::get_library() + .expect("We just loaded libclang and it had better still be here!")); + } else { + clang_sys::set_library(libclang.clone()); + } + } +} + /// Generated Rust bindings. #[derive(Debug)] pub struct Bindings<'ctx> { @@ -511,16 +540,14 @@ impl<'ctx> Bindings<'ctx> { span: Option) -> Result, ()> { let span = span.unwrap_or(DUMMY_SP); - if !clang_sys::is_loaded() { - // TODO(emilio): Return meaningful error (breaking). - clang_sys::load().expect("Unable to find libclang"); - } + ensure_libclang_is_loaded(); // TODO: Make this path fixup configurable? if let Some(clang) = clang_sys::support::Clang::find(None) { // 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.iter() + let has_target_arg = options.clang_args + .iter() .rposition(|arg| arg.starts_with("--target")) .is_some(); if !has_target_arg { @@ -644,7 +671,7 @@ pub fn parse_one(ctx: &mut BindgenContext, use clang_sys::CXChildVisit_Continue; match Item::parse(cursor, parent, ctx) { - Ok(..) => {}, + Ok(..) => {} Err(ParseError::Continue) => {} Err(ParseError::Recurse) => { cursor.visit(|child| parse_one(ctx, child, parent));