diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 001ad0e2be..c7e5198c9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,6 +12,7 @@ yourself. * [Running All Tests](#tests-all) * [Running a Single, Specific Test](#tests-one) * [Authoring New Tests](#tests-new) +* [Automatic Code Formatting](#formatting) * [Debug Logging](#logs) ## Code of Conduct @@ -95,6 +96,27 @@ specify the required features at the top of the test header in a similar manner: // bingden-features: llvm_stable ``` +## Automatic code formatting + +There's a `rustfmt.toml` file in the repo. Ideally changes should be consistent +with the style, though that's not enforced right now. + +[`rustfmt`](https://github.com/rust-lang-nursery/rustfmt) can catch and fix +automatically all the coding style issues it finds. In order to use it it +suffices to do: + +``` +$ cargo fmt +``` + +For it to work, you need to have `rustfmt` installed. To do so: + +``` +$ cargo install rustfmt +``` + +And ensure `~/.cargo/bin` is on your path. + ## Debug Logging To help debug what `bindgen` is doing, you can define the environment variable diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000000..96d4ae474d --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,10 @@ +max_width = 80 +format_strings = false +fn_brace_style = "SameLineWhere" +item_brace_style = "SameLineWhere" +struct_lit_multiline_style = "ForceMulti" +where_trailing_comma = true +reorder_imports = true +reorder_imported_names = true +normalize_comments = false +write_mode = "Overwrite" diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index 119776bdf5..2a7995e799 100755 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -8,13 +8,13 @@ extern crate log; extern crate clang_sys; extern crate rustc_serialize; -use bindgen::{Bindings, BindgenOptions, LinkType}; +use bindgen::{BindgenOptions, Bindings, LinkType}; use std::default::Default; +use std::env; +use std::fs; use std::io; use std::path; use std::process; -use std::env; -use std::fs; const USAGE: &'static str = " Usage: @@ -119,7 +119,8 @@ fn parse_args_or_exit(args: Vec) -> (BindgenOptions, Box) { options.links.push((lib, LinkType::Static)); } "--framework-link" => { - let lib = iter.next().expect("--framework-link needs an argument"); + let lib = iter.next() + .expect("--framework-link needs an argument"); options.links.push((lib, LinkType::Framework)); } "--raw-line" => { @@ -127,23 +128,28 @@ fn parse_args_or_exit(args: Vec) -> (BindgenOptions, Box) { options.raw_lines.push(line); } "--opaque-type" => { - let ty_canonical_name = iter.next().expect("--opaque-type expects a type"); + let ty_canonical_name = iter.next() + .expect("--opaque-type expects a type"); options.opaque_types.insert(ty_canonical_name); } "--blacklist-type" => { - let ty_canonical_name = iter.next().expect("--blacklist-type expects a type"); + let ty_canonical_name = iter.next() + .expect("--blacklist-type expects a type"); options.hidden_types.insert(ty_canonical_name); } "--whitelist-type" => { - let ty_pat = iter.next().expect("--whitelist-type expects a type pattern"); + let ty_pat = iter.next() + .expect("--whitelist-type expects a type pattern"); options.whitelisted_types.insert(&ty_pat); } "--whitelist-function" => { - let function_pat = iter.next().expect("--whitelist-function expects a pattern"); + let function_pat = iter.next() + .expect("--whitelist-function expects a pattern"); options.whitelisted_functions.insert(&function_pat); } "--whitelist-var" => { - let var_pat = iter.next().expect("--whitelist-var expects a pattern"); + let var_pat = iter.next() + .expect("--whitelist-var expects a pattern"); options.whitelisted_vars.insert(&var_pat); } "--" => { @@ -202,25 +208,31 @@ fn parse_args_or_exit(args: Vec) -> (BindgenOptions, Box) { pub fn main() { log::set_logger(|max_log_level| { - use env_logger::Logger; - let env_logger = Logger::new(); - max_log_level.set(env_logger.filter()); - Box::new(env_logger) - }).expect("Failed to set logger."); + use env_logger::Logger; + let env_logger = Logger::new(); + max_log_level.set(env_logger.filter()); + Box::new(env_logger) + }) + .expect("Failed to set logger."); let mut bind_args: Vec<_> = env::args().collect(); if let Some(clang) = clang_sys::support::Clang::find(None) { - let has_clang_args = bind_args.iter().rposition(|arg| *arg == "--").is_some(); + let has_clang_args = + bind_args.iter().rposition(|arg| *arg == "--").is_some(); if !has_clang_args { bind_args.push("--".to_owned()); } - // If --target is specified, assume caller knows what they're doing and don't mess with + // If --target is specified, assume caller knows what they're doing and + // don't mess with // include paths for them - let has_target_arg = bind_args.iter().rposition(|arg| arg.starts_with("--target")).is_some(); + let has_target_arg = bind_args.iter() + .rposition(|arg| arg.starts_with("--target")) + .is_some(); if !has_target_arg { - // TODO: distinguish C and C++ paths? C++'s should be enough, I guess. + // TODO: distinguish C and C++ paths? C++'s should be enough, I + // guess. for path in clang.cpp_search_paths.into_iter() { if let Ok(path) = path.into_os_string().into_string() { bind_args.push("-isystem".to_owned()); @@ -233,8 +245,8 @@ pub fn main() { let (options, out) = parse_args_or_exit(bind_args); let bindings = Bindings::generate(options, None) - .expect("Unable to generate bindings"); + .expect("Unable to generate bindings"); bindings.write(out) - .expect("Unable to write bindings to file."); + .expect("Unable to write bindings to file."); } diff --git a/src/clang.rs b/src/clang.rs index ba6fc7f68f..d69c8b14b5 100755 --- a/src/clang.rs +++ b/src/clang.rs @@ -3,27 +3,31 @@ #![allow(non_upper_case_globals, dead_code)] -use std::os::raw::{c_uint, c_char, c_int, c_ulong, c_longlong}; + +use clangll::*; use std::{mem, ptr}; +use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; use std::hash::Hasher; -use std::ffi::{CString, CStr}; - -use clangll::*; +use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong}; /// A cursor into the Clang AST, pointing to an AST node. /// /// We call the AST node pointed to by the cursor the cursor's "referent". #[derive(Copy, Clone)] pub struct Cursor { - x: CXCursor + x: CXCursor, } impl fmt::Debug for Cursor { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Cursor({} kind: {}, loc: {}, usr: {:?})", - self.spelling(), kind_to_str(self.kind()), self.location(), self.usr()) + write!(fmt, + "Cursor({} kind: {}, loc: {}, usr: {:?})", + self.spelling(), + kind_to_str(self.kind()), + self.location(), + self.usr()) } } @@ -32,7 +36,8 @@ impl fmt::Debug for Cursor { /// The first argument is the AST node currently being visited. The second /// argument is the parent of the AST node currently being visited. The return /// value informs how traversal should proceed. -pub type CursorVisitor<'s> = for<'a, 'b> FnMut(&'a Cursor, &'b Cursor) -> Enum_CXChildVisitResult + 's; +pub type CursorVisitor<'s> = for<'a, 'b> FnMut(&'a Cursor, &'b Cursor) + -> Enum_CXChildVisitResult + 's; impl Cursor { /// Get the Unified Symbol Resolution for this cursor's referent, if @@ -40,12 +45,8 @@ impl Cursor { /// /// The USR can be used to compare entities across translation units. pub fn usr(&self) -> Option { - let s = String_ { x: unsafe { clang_getCursorUSR(self.x) } }.to_string(); - if s.is_empty() { - None - } else { - Some(s) - } + let s: String = unsafe { clang_getCursorUSR(self.x) }.into(); + if s.is_empty() { None } else { Some(s) } } /// Is this cursor's referent a declaration? @@ -55,14 +56,14 @@ impl Cursor { /// Get the null cursor, which has no referent. pub fn null() -> Self { - Cursor { x: unsafe { clang_getNullCursor() } } + Cursor { + x: unsafe { clang_getNullCursor() }, + } } /// Get this cursor's referent's spelling. pub fn spelling(&self) -> String { - unsafe { - String_ { x: clang_getCursorSpelling(self.x) }.to_string() - } + unsafe { clang_getCursorSpelling(self.x).into() } } /// Get this cursor's referent's display name. @@ -70,16 +71,12 @@ impl Cursor { /// This is not necessarily a valid identifier. It includes extra /// information, such as parameters for a function, etc. pub fn display_name(&self) -> String { - unsafe { - String_ { x: clang_getCursorDisplayName(self.x) }.to_string() - } + unsafe { clang_getCursorDisplayName(self.x).into() } } /// Get the mangled name of this cursor's referent. pub fn mangling(&self) -> String { - unsafe { - String_ { x: clang_Cursor_getMangling(self.x) }.to_string() - } + unsafe { clang_Cursor_getMangling(self.x).into() } } /// Get the `Cursor` for this cursor's referent's lexical parent. @@ -101,7 +98,9 @@ impl Cursor { /// ``` pub fn lexical_parent(&self) -> Cursor { unsafe { - Cursor { x: clang_getCursorLexicalParent(self.x) } + Cursor { + x: clang_getCursorLexicalParent(self.x), + } } } @@ -123,7 +122,9 @@ impl Cursor { /// lexical parents. pub fn semantic_parent(&self) -> Cursor { unsafe { - Cursor { x: clang_getCursorSemanticParent(self.x) } + Cursor { + x: clang_getCursorSemanticParent(self.x), + } } } @@ -131,7 +132,7 @@ impl Cursor { /// if the referent is either a template specialization or /// declaration. Returns -1 otherwise. pub fn num_template_args(&self) -> Option { - let n : c_int = unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; + let n: c_int = unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; if n >= 0 { Some(n as u32) @@ -165,8 +166,7 @@ impl Cursor { while semantic_parent.kind() == CXCursor_Namespace || semantic_parent.kind() == CXCursor_NamespaceAlias || - semantic_parent.kind() == CXCursor_NamespaceRef - { + semantic_parent.kind() == CXCursor_NamespaceRef { semantic_parent = semantic_parent.semantic_parent(); } @@ -177,16 +177,12 @@ impl Cursor { /// Get the kind of referent this cursor is pointing to. pub fn kind(&self) -> Enum_CXCursorKind { - unsafe { - clang_getCursorKind(self.x) - } + unsafe { clang_getCursorKind(self.x) } } /// Is the referent an anonymous record definition? pub fn is_anonymous(&self) -> bool { - unsafe { - clang_Cursor_isAnonymous(self.x) != 0 - } + unsafe { clang_Cursor_isAnonymous(self.x) != 0 } } /// Is the referent a template specialization? @@ -208,49 +204,50 @@ impl Cursor { } let parent = self.semantic_parent(); (parent.is_template() && !parent.is_fully_specialized_template()) || - parent.is_in_non_fully_specialized_template() + parent.is_in_non_fully_specialized_template() } /// Is this cursor pointing a valid referent? pub fn is_valid(&self) -> bool { - unsafe { - clang_isInvalid(self.kind()) == 0 - } + unsafe { clang_isInvalid(self.kind()) == 0 } } /// Get the source location for the referent. pub fn location(&self) -> SourceLocation { unsafe { - SourceLocation { x: clang_getCursorLocation(self.x) } + SourceLocation { + x: clang_getCursorLocation(self.x), + } } } /// Get the source location range for the referent. pub fn extent(&self) -> CXSourceRange { - unsafe { - clang_getCursorExtent(self.x) - } + unsafe { clang_getCursorExtent(self.x) } } /// Get the raw declaration comment for this referent, if one exists. pub fn raw_comment(&self) -> Option { - let s = unsafe { - String_ { x: clang_Cursor_getRawCommentText(self.x) }.to_string() - }; + let s: String = + unsafe { clang_Cursor_getRawCommentText(self.x).into() }; if s.is_empty() { None } else { Some(s) } } /// Get the referent's parsed comment. pub fn comment(&self) -> Comment { unsafe { - Comment { x: clang_Cursor_getParsedComment(self.x) } + Comment { + x: clang_Cursor_getParsedComment(self.x), + } } } /// Get the referent's type. pub fn cur_type(&self) -> Type { unsafe { - Type { x: clang_getCursorType(self.x) } + Type { + x: clang_getCursorType(self.x), + } } } @@ -259,7 +256,9 @@ impl Cursor { /// the declared thing. pub fn definition(&self) -> Cursor { unsafe { - Cursor { x: clang_getCursorDefinition(self.x) } + Cursor { + x: clang_getCursorDefinition(self.x), + } } } @@ -267,7 +266,9 @@ impl Cursor { /// pointing to the referenced type. pub fn referenced(&self) -> Cursor { unsafe { - Cursor { x: clang_getCursorReferenced(self.x) } + Cursor { + x: clang_getCursorReferenced(self.x), + } } } @@ -278,7 +279,9 @@ impl Cursor { /// referent type. pub fn canonical(&self) -> Cursor { unsafe { - Cursor { x: clang_getCanonicalCursor(self.x) } + Cursor { + x: clang_getCanonicalCursor(self.x), + } } } @@ -286,7 +289,9 @@ impl Cursor { /// pointing to the template definition that is being specialized. pub fn specialized(&self) -> Cursor { unsafe { - Cursor { x: clang_getSpecializedCursorTemplate(self.x) } + Cursor { + x: clang_getSpecializedCursorTemplate(self.x), + } } } @@ -302,10 +307,15 @@ impl Cursor { /// for details on arguments passed to the function and how its return value /// is interpreted. pub fn visit(&self, func: F) - where F: for<'a, 'b> FnMut(&'a Cursor, &'b Cursor) -> Enum_CXChildVisitResult + where F: for<'a, 'b> FnMut(&'a Cursor, &'b Cursor) + -> Enum_CXChildVisitResult, { let mut data: Box = Box::new(func); - let opt_visit = Some(visit_children as extern "C" fn(CXCursor, CXCursor, CXClientData) -> Enum_CXChildVisitResult); + let opt_visit = + Some(visit_children as extern "C" fn(CXCursor, + CXCursor, + CXClientData) + -> Enum_CXChildVisitResult); unsafe { clang_visitChildren(self.x, opt_visit, mem::transmute(&mut data)); } @@ -332,11 +342,7 @@ impl Cursor { pub fn bit_width(&self) -> Option { unsafe { let w = clang_getFieldDeclBitWidth(self.x); - if w == -1 { - None - } else { - Some(w as u32) - } + if w == -1 { None } else { Some(w as u32) } } } @@ -344,7 +350,9 @@ impl Cursor { /// enum type. pub fn enum_type(&self) -> Type { unsafe { - Type { x: clang_getEnumDeclIntegerType(self.x) } + Type { + x: clang_getEnumDeclIntegerType(self.x), + } } } @@ -354,9 +362,7 @@ impl Cursor { /// which is also a valid enum value, so callers should check the cursor /// kind before calling this method (see issue #127). pub fn enum_val_signed(&self) -> i64 { - unsafe { - clang_getEnumConstantDeclValue(self.x) as i64 - } + unsafe { clang_getEnumConstantDeclValue(self.x) as i64 } } /// Get the unsigned constant value for this cursor's enum variant referent. @@ -365,16 +371,16 @@ impl Cursor { /// which is also a valid enum value, so callers should check the cursor /// kind before calling this method (see issue #128). pub fn enum_val_unsigned(&self) -> u64 { - unsafe { - clang_getEnumConstantDeclUnsignedValue(self.x) as u64 - } + unsafe { clang_getEnumConstantDeclUnsignedValue(self.x) as u64 } } /// Given that this cursor's referent is a `typedef`, get the `Type` that is /// being aliased. pub fn typedef_type(&self) -> Type { unsafe { - Type { x: clang_getTypedefDeclUnderlyingType(self.x) } + Type { + x: clang_getTypedefDeclUnderlyingType(self.x), + } } } @@ -382,16 +388,12 @@ impl Cursor { /// /// This only applies to functions and variables. pub fn linkage(&self) -> Enum_CXLinkageKind { - unsafe { - clang_getCursorLinkage(self.x) - } + unsafe { clang_getCursorLinkage(self.x) } } /// Get the visibility of this cursor's referent. pub fn visibility(&self) -> Enum_CXVisibilityKind { - unsafe { - clang_getCursorVisibility(self.x) - } + unsafe { clang_getCursorVisibility(self.x) } } /// Given that this cursor's referent is a function, return cursors to its @@ -401,7 +403,9 @@ impl Cursor { let num = self.num_args().expect("expected value, got none") as u32; let mut args = vec![]; for i in 0..num { - args.push(Cursor { x: clang_Cursor_getArgument(self.x, i as c_uint) }); + args.push(Cursor { + x: clang_Cursor_getArgument(self.x, i as c_uint), + }); } args } @@ -411,7 +415,9 @@ impl Cursor { /// declaration, return a cursor to its return type. pub fn ret_type(&self) -> Type { unsafe { - Type { x: clang_getCursorResultType(self.x) } + Type { + x: clang_getCursorResultType(self.x), + } } } @@ -423,55 +429,39 @@ impl Cursor { pub fn num_args(&self) -> Result { unsafe { let w = clang_Cursor_getNumArguments(self.x); - if w == -1 { - Err(()) - } else { - Ok(w as u32) - } + if w == -1 { Err(()) } else { Ok(w as u32) } } } /// Get the access specifier for this cursor's referent. pub fn access_specifier(&self) -> Enum_CX_CXXAccessSpecifier { - unsafe { - clang_getCXXAccessSpecifier(self.x) - } + unsafe { clang_getCXXAccessSpecifier(self.x) } } /// Is this cursor's referent a field declaration that is marked as /// `mutable`? pub fn is_mutable_field(&self) -> bool { - unsafe { - clang_CXXField_isMutable(self.x) != 0 - } + unsafe { clang_CXXField_isMutable(self.x) != 0 } } /// Is this cursor's referent a member function that is declared `static`? pub fn method_is_static(&self) -> bool { - unsafe { - clang_CXXMethod_isStatic(self.x) != 0 - } + unsafe { clang_CXXMethod_isStatic(self.x) != 0 } } /// Is this cursor's referent a member function that is declared `const`? pub fn method_is_const(&self) -> bool { - unsafe { - clang_CXXMethod_isConst(self.x) != 0 - } + unsafe { clang_CXXMethod_isConst(self.x) != 0 } } /// Is this cursor's referent a member function that is declared `const`? pub fn method_is_virtual(&self) -> bool { - unsafe { - clang_CXXMethod_isVirtual(self.x) != 0 - } + unsafe { clang_CXXMethod_isVirtual(self.x) != 0 } } /// Is this cursor's referent a struct or class with virtual members? pub fn is_virtual_base(&self) -> bool { - unsafe { - clang_isVirtualBase(self.x) != 0 - } + unsafe { clang_isVirtualBase(self.x) != 0 } } /// Given that this cursor's referent is a template specialization or @@ -480,32 +470,33 @@ impl Cursor { /// If the referent is not a template or `i` is out of bounds, an invalid /// kind is returned. pub fn template_arg_kind(&self, i: c_int) -> CXTemplateArgumentKind { - unsafe { - clang_Cursor_getTemplateArgumentKind(self.x, i as c_uint) - } + unsafe { clang_Cursor_getTemplateArgumentKind(self.x, i as c_uint) } } /// Given that this cursor's referent is a template specialization, and that /// the `i`th template argument is an integral, get the `i`th template /// argument value. pub fn template_arg_value(&self, i: c_int) -> c_longlong { - unsafe { - clang_Cursor_getTemplateArgumentValue(self.x, i as c_uint) - } + unsafe { clang_Cursor_getTemplateArgumentValue(self.x, i as c_uint) } } } -extern fn visit_children(cur: CXCursor, parent: CXCursor, - data: CXClientData) -> Enum_CXChildVisitResult { +extern "C" fn visit_children(cur: CXCursor, + parent: CXCursor, + data: CXClientData) + -> Enum_CXChildVisitResult { let func: &mut Box = unsafe { mem::transmute(data) }; - (*func)(&Cursor { x : cur }, &Cursor { x: parent }) + (*func)(&Cursor { + x: cur, + }, + &Cursor { + x: parent, + }) } impl PartialEq for Cursor { fn eq(&self, other: &Cursor) -> bool { - unsafe { - clang_equalCursors(self.x, other.x) == 1 - } + unsafe { clang_equalCursors(self.x, other.x) == 1 } } } @@ -520,14 +511,12 @@ impl Hash for Cursor { /// The type of a node in clang's AST. #[derive(Clone, Hash)] pub struct Type { - x: CXType + x: CXType, } impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { - unsafe { - clang_equalTypes(self.x, other.x) != 0 - } + unsafe { clang_equalTypes(self.x, other.x) != 0 } } } @@ -535,8 +524,11 @@ impl Eq for Type {} impl fmt::Debug for Type { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Type({}, kind: {}, decl: {:?}, canon: {:?})", - self.spelling(), type_to_str(self.kind()), self.declaration(), + write!(fmt, + "Type({}, kind: {}, decl: {:?}, canon: {:?})", + self.spelling(), + type_to_str(self.kind()), + self.declaration(), self.declaration().canonical()) } } @@ -582,22 +574,20 @@ impl Type { /// Get a cursor pointing to this type's declaration. pub fn declaration(&self) -> Cursor { unsafe { - Cursor { x: clang_getTypeDeclaration(self.x) } + Cursor { + x: clang_getTypeDeclaration(self.x), + } } } /// Get a raw display name for this type. pub fn spelling(&self) -> String { - unsafe { - String_ { x: clang_getTypeSpelling(self.x) }.to_string() - } + unsafe { clang_getTypeSpelling(self.x).into() } } /// Is this type const qualified? pub fn is_const(&self) -> bool { - unsafe { - clang_isConstQualifiedType(self.x) != 0 - } + unsafe { clang_isConstQualifiedType(self.x) != 0 } } /// What is the size of this type? Paper over invalid types by returning `0` @@ -657,7 +647,7 @@ impl Type { Some(TypeTemplateArgIterator { x: self.x, length: n as u32, - index: 0 + index: 0, }) } else { debug_assert_eq!(n, -1); @@ -669,14 +659,18 @@ impl Type { /// to. pub fn pointee_type(&self) -> Type { unsafe { - Type { x: clang_getPointeeType(self.x) } + Type { + x: clang_getPointeeType(self.x), + } } } /// Given that this type is an array, vector, or complex type, return the /// type of its elements. pub fn elem_type(&self) -> Option { - let current_type = Type { x: unsafe { clang_getElementType(self.x) } }; + let current_type = Type { + x: unsafe { clang_getElementType(self.x) }, + }; if current_type.kind() != CXType_Invalid { Some(current_type) } else { @@ -699,15 +693,15 @@ impl Type { /// aliases to get the underlying, canonical type. pub fn canonical_type(&self) -> Type { unsafe { - Type { x: clang_getCanonicalType(self.x) } + Type { + x: clang_getCanonicalType(self.x), + } } } /// Is this type a variadic function type? pub fn is_variadic(&self) -> bool { - unsafe { - clang_isFunctionTypeVariadic(self.x) != 0 - } + unsafe { clang_isFunctionTypeVariadic(self.x) != 0 } } /// Given that this type is a function type, get the types of its @@ -715,9 +709,11 @@ impl Type { pub fn arg_types(&self) -> Vec { unsafe { let num = clang_getNumArgTypes(self.x) as usize; - let mut args = vec!(); + let mut args = vec![]; for i in 0..num { - args.push(Type { x: clang_getArgType(self.x, i as c_uint) }); + args.push(Type { + x: clang_getArgType(self.x, i as c_uint), + }); } args } @@ -726,7 +722,9 @@ impl Type { /// Given that this type is a function type, get the type of its return /// value. pub fn ret_type(&self) -> Option { - let rt = Type { x: unsafe { clang_getResultType(self.x) } }; + let rt = Type { + x: unsafe { clang_getResultType(self.x) }, + }; if rt.kind() == CXType_Invalid { None } else { @@ -737,9 +735,7 @@ impl Type { /// Given that this type is a function type, get its calling convention. If /// this is not a function type, `CXCallingConv_Invalid` is returned. pub fn call_conv(&self) -> Enum_CXCallingConv { - unsafe { - clang_getFunctionTypeCallingConv(self.x) - } + unsafe { clang_getFunctionTypeCallingConv(self.x) } } /// For elaborated types (types which use `class`, `struct`, or `union` to @@ -747,7 +743,9 @@ impl Type { #[cfg(not(feature="llvm_stable"))] pub fn named(&self) -> Type { unsafe { - Type { x: clang_Type_getNamedType(self.x) } + Type { + x: clang_Type_getNamedType(self.x), + } } } } @@ -756,7 +754,7 @@ impl Type { pub struct TypeTemplateArgIterator { x: CXType, length: u32, - index: u32 + index: u32, } impl Iterator for TypeTemplateArgIterator { @@ -765,7 +763,9 @@ impl Iterator for TypeTemplateArgIterator { if self.index < self.length { let idx = self.index as c_int; self.index += 1; - Some(Type { x: unsafe { clang_Type_getTemplateArgumentAsType(self.x, idx) } }) + Some(Type { + x: unsafe { clang_Type_getTemplateArgumentAsType(self.x, idx) }, + }) } else { None } @@ -782,7 +782,7 @@ impl ExactSizeIterator for TypeTemplateArgIterator { /// A `SourceLocation` is a file, line, column, and byte offset location for /// some source text. pub struct SourceLocation { - x: CXSourceLocation + x: CXSourceLocation, } impl SourceLocation { @@ -794,8 +794,17 @@ impl SourceLocation { let mut line = 0; let mut col = 0; let mut off = 0; - clang_getSpellingLocation(self.x, &mut file, &mut line, &mut col, &mut off); - (File { x: file }, line as usize, col as usize, off as usize) + clang_getSpellingLocation(self.x, + &mut file, + &mut line, + &mut col, + &mut off); + (File { + x: file, + }, + line as usize, + col as usize, + off as usize) } } } @@ -815,15 +824,13 @@ impl fmt::Display for SourceLocation { /// /// Comments are sort of parsed by Clang, and have a tree structure. pub struct Comment { - x: CXComment + x: CXComment, } impl Comment { /// What kind of comment is this? pub fn kind(&self) -> Enum_CXCommentKind { - unsafe { - clang_Comment_getKind(self.x) - } + unsafe { clang_Comment_getKind(self.x) } } /// Get this comment's children comment @@ -831,16 +838,14 @@ impl Comment { CommentChildrenIterator { parent: self.x, length: unsafe { clang_Comment_getNumChildren(self.x) }, - index: 0 + index: 0, } } /// 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 { - String_ { x: clang_HTMLTagComment_getTagName(self.x) }.to_string() - } + unsafe { clang_HTMLTagComment_getTagName(self.x).into() } } /// Given that this comment is an HTML start tag, get its attributes. @@ -848,7 +853,7 @@ impl Comment { CommentAttributesIterator { x: self.x, length: unsafe { clang_HTMLStartTag_getNumAttrs(self.x) }, - index: 0 + index: 0, } } } @@ -857,7 +862,7 @@ impl Comment { pub struct CommentChildrenIterator { parent: CXComment, length: c_uint, - index: c_uint + index: c_uint, } impl Iterator for CommentChildrenIterator { @@ -866,7 +871,9 @@ impl Iterator for CommentChildrenIterator { if self.index < self.length { let idx = self.index; self.index += 1; - Some( Comment { x: unsafe { clang_Comment_getChild(self.parent, idx) } } ) + Some(Comment { + x: unsafe { clang_Comment_getChild(self.parent, idx) }, + }) } else { None } @@ -878,14 +885,14 @@ pub struct CommentAttribute { /// HTML start tag attribute name pub name: String, /// HTML start tag attribute value - pub value: String + pub value: String, } /// An iterator for a comment's attributes pub struct CommentAttributesIterator { x: CXComment, length: c_uint, - index: c_uint + index: c_uint, } impl Iterator for CommentAttributesIterator { @@ -894,9 +901,13 @@ impl Iterator for CommentAttributesIterator { if self.index < self.length { let idx = self.index; self.index += 1; - Some( CommentAttribute { - name: String_ { x: unsafe { clang_HTMLStartTag_getAttrName(self.x, idx) } }.to_string(), - value: String_ { x: unsafe { clang_HTMLStartTag_getAttrValue(self.x, idx) } }.to_string() + Some(CommentAttribute { + name: unsafe { + clang_HTMLStartTag_getAttrName(self.x, idx).into() + }, + value: unsafe { + clang_HTMLStartTag_getAttrValue(self.x, idx).into() + }, }) } else { None @@ -906,7 +917,7 @@ impl Iterator for CommentAttributesIterator { /// A source file. pub struct File { - x: CXFile + x: CXFile, } impl File { @@ -915,26 +926,18 @@ impl File { if self.x.is_null() { return None; } - unsafe { - Some(String_ { x: clang_getFileName(self.x) }.to_string()) - } + unsafe { Some(clang_getFileName(self.x).into()) } } } -/// A Clang string. -pub struct String_ { - x: CXString -} - -impl fmt::Display for String_ { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.x.data.is_null() { - return "".fmt(f); +impl Into for CXString { + fn into(self) -> String { + if self.data.is_null() { + return "".to_owned(); } unsafe { - let c_str = clang_getCString(self.x) as *const c_char; - let p = c_str as *const _; - f.write_str(&String::from_utf8_lossy(CStr::from_ptr(p).to_bytes())) + let c_str = CStr::from_ptr(clang_getCString(self) as *const _); + c_str.to_string_lossy().into_owned() } } } @@ -942,7 +945,7 @@ impl fmt::Display for String_ { /// An `Index` is an environment for a set of translation units that will /// typically end up linked together in one final binary. pub struct Index { - x: CXIndex + x: CXIndex, } impl Index { @@ -954,7 +957,9 @@ impl Index { /// The `diag` parameter controls whether debugging diagnostics are enabled. pub fn new(pch: bool, diag: bool) -> Index { unsafe { - Index { x: clang_createIndex(pch as c_int, diag as c_int) } + Index { + x: clang_createIndex(pch as c_int, diag as c_int), + } } } } @@ -984,7 +989,7 @@ pub struct Token { /// A translation unit (or "compilation unit"). pub struct TranslationUnit { - x: CXTranslationUnit + x: CXTranslationUnit, } impl fmt::Debug for TranslationUnit { @@ -995,14 +1000,22 @@ impl fmt::Debug for TranslationUnit { impl TranslationUnit { /// Parse a source file into a translation unit. - pub fn parse(ix: &Index, file: &str, cmd_args: &[String], - unsaved: &[UnsavedFile], opts: ::libc::c_uint) -> Option { + pub fn parse(ix: &Index, + file: &str, + cmd_args: &[String], + unsaved: &[UnsavedFile], + opts: ::libc::c_uint) + -> Option { let fname = CString::new(file).unwrap(); - let _c_args: Vec = cmd_args.iter().map(|s| CString::new(s.clone()).unwrap()).collect(); - let c_args: Vec<*const c_char> = _c_args.iter().map(|s| s.as_ptr()).collect(); - let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); + let _c_args: Vec = + cmd_args.iter().map(|s| CString::new(s.clone()).unwrap()).collect(); + let c_args: Vec<*const c_char> = + _c_args.iter().map(|s| s.as_ptr()).collect(); + let mut c_unsaved: Vec = + unsaved.iter().map(|f| f.x).collect(); let tu = unsafe { - clang_parseTranslationUnit(ix.x, fname.as_ptr(), + clang_parseTranslationUnit(ix.x, + fname.as_ptr(), c_args.as_ptr(), c_args.len() as c_int, c_unsaved.as_mut_ptr(), @@ -1012,14 +1025,17 @@ impl TranslationUnit { if tu.is_null() { None } else { - Some(TranslationUnit { x: tu }) + Some(TranslationUnit { + x: tu, + }) } } /// Reparse this translation unit, maybe because the file changed on disk or /// something like that. pub fn reparse(&self, unsaved: &[UnsavedFile], opts: usize) -> bool { - let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); + let mut c_unsaved: Vec = + unsaved.iter().map(|f| f.x).collect(); unsafe { clang_reparseTranslationUnit(self.x, @@ -1034,9 +1050,11 @@ impl TranslationUnit { pub fn diags(&self) -> Vec { unsafe { let num = clang_getNumDiagnostics(self.x) as usize; - let mut diags = vec!(); + let mut diags = vec![]; for i in 0..num { - diags.push(Diagnostic { x: clang_getDiagnostic(self.x, i as c_uint) }); + diags.push(Diagnostic { + x: clang_getDiagnostic(self.x, i as c_uint), + }); } diags } @@ -1045,7 +1063,9 @@ impl TranslationUnit { /// Get a cursor pointing to the root of this translation unit's AST. pub fn cursor(&self) -> Cursor { unsafe { - Cursor { x: clang_getTranslationUnitCursor(self.x) } + Cursor { + x: clang_getTranslationUnitCursor(self.x), + } } } @@ -1061,16 +1081,22 @@ impl TranslationUnit { let mut tokens = vec![]; unsafe { let mut token_ptr = ::std::ptr::null_mut(); - let mut num_tokens : c_uint = 0; + let mut num_tokens: c_uint = 0; clang_tokenize(self.x, range, &mut token_ptr, &mut num_tokens); if token_ptr.is_null() { return None; } - let token_array = ::std::slice::from_raw_parts(token_ptr, num_tokens as usize); + let token_array = ::std::slice::from_raw_parts(token_ptr, + num_tokens as usize); for &token in token_array.iter() { let kind = clang_getTokenKind(token); - let spelling = String_ { x: clang_getTokenSpelling(self.x, token) }.to_string(); - tokens.push(Token { kind: kind, spelling: spelling }); + let spelling: String = clang_getTokenSpelling(self.x, token) + .into(); + + tokens.push(Token { + kind: kind, + spelling: spelling, + }); } clang_disposeTokens(self.x, token_ptr, num_tokens); } @@ -1089,30 +1115,24 @@ impl Drop for TranslationUnit { /// A diagnostic message generated while parsing a translation unit. pub struct Diagnostic { - x: CXDiagnostic + x: CXDiagnostic, } impl Diagnostic { /// Get the default diagnostic display option bit flags. pub fn default_opts() -> usize { - unsafe { - clang_defaultDiagnosticDisplayOptions() as usize - } + unsafe { clang_defaultDiagnosticDisplayOptions() as usize } } /// Format this diagnostic message as a string, using the given option bit /// flags. pub fn format(&self, opts: usize) -> String { - unsafe { - String_ { x: clang_formatDiagnostic(self.x, opts as c_uint) }.to_string() - } + unsafe { clang_formatDiagnostic(self.x, opts as c_uint).into() } } /// What is the severity of this diagnostic message? pub fn severity(&self) -> Enum_CXDiagnosticSeverity { - unsafe { - clang_getDiagnosticSeverity(self.x) - } + unsafe { clang_getDiagnosticSeverity(self.x) } } } @@ -1129,7 +1149,7 @@ impl Drop for Diagnostic { pub struct UnsavedFile { x: Struct_CXUnsavedFile, name: CString, - contents: CString + contents: CString, } impl UnsavedFile { @@ -1145,7 +1165,7 @@ impl UnsavedFile { UnsavedFile { x: x, name: name, - contents: contents + contents: contents, } } } @@ -1184,7 +1204,12 @@ pub fn kind_to_str(x: Enum_CXCursorKind) -> &'static str { CXCursor_TemplateTemplateParameter => "TemplateTemplateParameter", CXCursor_FunctionTemplate => "FunctionTemplate", CXCursor_ClassTemplate => "ClassTemplate", - CXCursor_ClassTemplatePartialSpecialization => "ClassTemplatePartialSpecialization", + CXCursor_ClassTemplatePartialSpecialization => { + // FIXME: Ugly hack for rustfmt, should go away! + // + // I plan to convert this into an enum right away anyway, though. + return "ClassTemplatePartialSpecialization"; + } CXCursor_NamespaceAlias => "NamespaceAlias", CXCursor_UsingDirective => "UsingDirective", CXCursor_UsingDeclaration => "UsingDeclaration", @@ -1310,8 +1335,8 @@ pub fn kind_to_str(x: Enum_CXCursorKind) -> &'static str { CXCursor_MacroExpansion => "MacroExpansion", // CXCursor_MacroInstantiation => "MacroInstantiation", CXCursor_InclusionDirective => "InclusionDirective", - //CXCursor_FirstPreprocessing => "FirstPreprocessing", - //CXCursor_LastPreprocessing => "LastPreprocessing", + // CXCursor_FirstPreprocessing => "FirstPreprocessing", + // CXCursor_LastPreprocessing => "LastPreprocessing", CXCursor_PackedAttr => "PackedAttr", CXCursor_ModuleImportDecl => "ModuleImportDecl", CXCursor_TypeAliasTemplateDecl => "TypeAliasTemplateDecl", @@ -1327,15 +1352,15 @@ pub fn type_to_str(x: Enum_CXTypeKind) -> &'static str { CXType_Unexposed => "Unexposed", CXType_Void => "Void", CXType_Bool => "Bool", - CXType_Char_U => "Char_U", + CXType_Char_U => "Char_U", CXType_UChar => "UChar", - CXType_Char16=> "Char16", - CXType_Char32=> "Char32", + CXType_Char16 => "Char16", + CXType_Char32 => "Char32", CXType_UShort => "UShort", CXType_UInt => "UInt", CXType_ULong => "ULong", CXType_ULongLong => "ULongLong", - CXType_UInt128=>"UInt128", + CXType_UInt128 => "UInt128", CXType_Char_S => "Char_S", CXType_SChar => "SChar", CXType_WChar => "WChar", @@ -1343,7 +1368,7 @@ pub fn type_to_str(x: Enum_CXTypeKind) -> &'static str { CXType_Int => "Int", CXType_Long => "Long", CXType_LongLong => "LongLong", - CXType_Int128=>"Int128", + CXType_Int128 => "Int128", CXType_Float => "Float", CXType_Double => "Double", CXType_LongDouble => "LongDouble", @@ -1377,12 +1402,12 @@ pub fn type_to_str(x: Enum_CXTypeKind) -> &'static str { CXType_Auto => "Auto", #[cfg(not(feature="llvm_stable"))] CXType_Elaborated => "Elaborated", - _ => "?" + _ => "?", } } /// Dump the Clang AST to stdout for debugging purposes. -pub fn ast_dump(c: &Cursor, depth: isize)-> Enum_CXVisitorResult { +pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult { fn print_indent(depth: isize, s: &str) { let mut i = 0; while i < depth { @@ -1392,14 +1417,12 @@ pub fn ast_dump(c: &Cursor, depth: isize)-> Enum_CXVisitorResult { println!("{}", s); } let ct = c.cur_type().kind(); - print_indent(depth, &format!("({} {} {}", - kind_to_str(c.kind()), - c.spelling(), - type_to_str(ct)) - ); - c.visit(| s, _: &Cursor| { - ast_dump(s, depth + 1) - }); + print_indent(depth, + &format!("({} {} {}", + kind_to_str(c.kind()), + c.spelling(), + type_to_str(ct))); + c.visit(|s, _: &Cursor| ast_dump(s, depth + 1)); print_indent(depth, ")"); CXChildVisit_Continue } diff --git a/src/clangll.rs b/src/clangll.rs index 272fa5741c..b89c07569f 100644 --- a/src/clangll.rs +++ b/src/clangll.rs @@ -5,6 +5,7 @@ #![allow(unused_attributes)] #![allow(non_snake_case)] #![allow(non_upper_case_globals)] +#![cfg_attr(rustfmt, rustfmt_skip)] use ::std::os::raw::{ c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ulonglong, c_void}; diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index e82d5c59de..234dcbcc0c 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -1,4 +1,4 @@ -/// Helpers for code generation that don't need macro expansion. +//! Helpers for code generation that don't need macro expansion. use aster; use ir::layout::Layout; diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index a656c2c13a..5717390401 100755 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,32 +1,32 @@ mod helpers; -use self::helpers::{attributes, BlobTyBuilder}; +use aster; + +use ir::annotations::FieldAccessorKind; +use ir::comp::{CompInfo, CompKind, Field, Method}; use ir::context::BindgenContext; -use ir::item::{Item, ItemId, ItemCanonicalName, ItemCanonicalPath}; -use ir::ty::{Type, TypeKind}; -use ir::int::IntKind; -use ir::module::Module; -use ir::var::Var; use ir::enum_ty::Enum; use ir::function::{Function, FunctionSig}; +use ir::int::IntKind; +use ir::item::{Item, ItemCanonicalName, ItemCanonicalPath, ItemId}; use ir::item_kind::ItemKind; -use ir::comp::{CompKind, CompInfo, Field, Method}; use ir::layout::Layout; -use ir::annotations::FieldAccessorKind; +use ir::module::Module; +use ir::ty::{Type, TypeKind}; use ir::type_collector::{ItemSet, TypeCollector}; +use ir::var::Var; +use self::helpers::{BlobTyBuilder, attributes}; -use std::ops; use std::borrow::Cow; -use std::mem; use std::collections::HashSet; -use std::collections::hash_map::{HashMap, Entry}; - +use std::collections::hash_map::{Entry, HashMap}; +use std::mem; +use std::ops; use syntax::abi::Abi; use syntax::ast; use syntax::codemap::{Span, respan}; use syntax::ptr::P; -use aster; fn root_import(ctx: &BindgenContext) -> P { assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up"); @@ -39,8 +39,8 @@ struct CodegenResult { items: Vec>, saw_union: bool, items_seen: HashSet, - /// The set of generated function/var names, needed because in C/C++ is legal to - /// do something like: + /// The set of generated function/var names, needed because in C/C++ is + /// legal to do something like: /// /// ```c++ /// extern "C" { @@ -99,7 +99,7 @@ impl CodegenResult { } fn inner(&mut self, cb: F) -> Vec> - where F: FnOnce(&mut Self) + where F: FnOnce(&mut Self), { let mut new = Self::new(); @@ -135,7 +135,7 @@ impl ForeignModBuilder { inner: ast::ForeignMod { abi: abi, items: vec![], - } + }, } } @@ -146,7 +146,7 @@ impl ForeignModBuilder { #[allow(dead_code)] fn with_foreign_items(mut self, items: I) -> Self - where I: IntoIterator + where I: IntoIterator, { self.inner.items.extend(items.into_iter()); self @@ -182,7 +182,7 @@ impl ToPtr for P { ast::Mutability::Immutable } else { ast::Mutability::Mutable - } + }, }); P(ast::Ty { id: ast::DUMMY_NODE_ID, @@ -217,20 +217,21 @@ impl CodeGenerator for Item { match *self.kind() { ItemKind::Module(ref module) => { - if !ctx.options().enable_cxx_namespaces && self.id() == ctx.root_module() { + if !ctx.options().enable_cxx_namespaces && + self.id() == ctx.root_module() { return; } module.codegen(ctx, result, self); - }, + } ItemKind::Function(ref fun) => { if !ctx.options().ignore_functions { fun.codegen(ctx, result, self); } - }, + } ItemKind::Var(ref var) => { var.codegen(ctx, result, self); - }, + } ItemKind::Type(ref ty) => { ty.codegen(ctx, result, self); } @@ -265,8 +266,10 @@ impl CodeGenerator for Module { }); let name = item.canonical_name(ctx); - let item = aster::AstBuilder::new().item().pub_() - .build_item_kind(name, module); + let item = aster::AstBuilder::new() + .item() + .pub_() + .build_item_kind(name, module); result.push(item); } @@ -288,9 +291,13 @@ impl CodeGenerator for Var { let ty = self.ty().to_rust_ty(ctx); if let Some(val) = self.val() { - let const_item = aster::AstBuilder::new().item().pub_() - .const_(canonical_name) - .expr().int(val).build(ty); + let const_item = aster::AstBuilder::new() + .item() + .pub_() + .const_(canonical_name) + .expr() + .int(val) + .build(ty); result.push(const_item) } else { let mut attrs = vec![]; @@ -310,8 +317,8 @@ impl CodeGenerator for Var { }; let item = ForeignModBuilder::new(Abi::C) - .with_foreign_item(item) - .build(ctx); + .with_foreign_item(item) + .build(ctx); result.push(item); } } @@ -368,7 +375,8 @@ impl CodeGenerator for Type { return; } - let mut applicable_template_args = item.applicable_template_args(ctx); + let mut applicable_template_args = + item.applicable_template_args(ctx); let inner_rust_type = if item.is_opaque(ctx) { applicable_template_args.clear(); // Pray if there's no layout. @@ -391,10 +399,12 @@ impl CodeGenerator for Type { if template_arg.is_named() { let name = template_arg.name().unwrap(); if name.contains("typename ") { - error!("Item contained `typename`'d template param: {:?}", item); + error!("Item contained `typename`'d template \ + parameter: {:?}", item); return; } - generics = generics.ty_param_id(template_arg.name().unwrap()); + generics = + generics.ty_param_id(template_arg.name().unwrap()); } } @@ -402,8 +412,9 @@ impl CodeGenerator for Type { result.push(typedef) } TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item), - ref u @ TypeKind::UnresolvedTypeRef(..) - => unreachable!("Should have been resolved after parsing {:?}!", u), + ref u @ TypeKind::UnresolvedTypeRef(..) => { + unreachable!("Should have been resolved after parsing {:?}!", u) + } } } } @@ -417,7 +428,10 @@ struct Vtable<'a> { } impl<'a> Vtable<'a> { - fn new(item_id: ItemId, methods: &'a [Method], base_classes: &'a [ItemId]) -> Self { + fn new(item_id: ItemId, + methods: &'a [Method], + base_classes: &'a [ItemId]) + -> Self { Vtable { item_id: item_id, methods: methods, @@ -436,10 +450,12 @@ impl<'a> CodeGenerator for Vtable<'a> { assert_eq!(item.id(), self.item_id); // For now, generate an empty struct, later we should generate function // pointers and whatnot. - let vtable = aster::AstBuilder::new().item().pub_() - .with_attr(attributes::repr("C")) - .struct_(self.canonical_name(ctx)) - .build(); + let vtable = aster::AstBuilder::new() + .item() + .pub_() + .with_attr(attributes::repr("C")) + .struct_(self.canonical_name(ctx)) + .build(); result.push(vtable); } } @@ -475,8 +491,9 @@ impl<'a> Bitfield<'a> { methods: &mut Vec) { use aster::struct_field::StructFieldBuilder; use std::cmp; - let mut total_width = self.fields.iter() - .fold(0u32, |acc, f| acc + f.bitfield().unwrap()); + let mut total_width = self.fields + .iter() + .fold(0u32, |acc, f| acc + f.bitfield().unwrap()); if !total_width.is_power_of_two() || total_width < 8 { total_width = cmp::max(8, total_width.next_power_of_two()); @@ -485,11 +502,14 @@ impl<'a> Bitfield<'a> { let total_width_in_bytes = total_width as usize / 8; let bitfield_type = - BlobTyBuilder::new(Layout::new(total_width_in_bytes, total_width_in_bytes)).build(); + BlobTyBuilder::new(Layout::new(total_width_in_bytes, + total_width_in_bytes)) + .build(); let field_name = format!("_bitfield_{}", self.index); let field_ident = ctx.ext_cx().ident_of(&field_name); - let field = StructFieldBuilder::named(&field_name).pub_() - .build_ty(bitfield_type.clone()); + let field = StructFieldBuilder::named(&field_name) + .pub_() + .build_ty(bitfield_type.clone()); fields.push(field); @@ -497,19 +517,21 @@ impl<'a> Bitfield<'a> { for field in self.fields { let width = field.bitfield().unwrap(); let field_name = field.name() - .map(ToOwned::to_owned) - .unwrap_or_else(|| format!("at_offset_{}", offset)); + .map(ToOwned::to_owned) + .unwrap_or_else(|| format!("at_offset_{}", offset)); let field_item = ctx.resolve_item(field.ty()); - let field_ty_layout = field_item.kind().expect_type() - .layout(ctx) - .expect("Bitfield without layout? Gah!"); + let field_ty_layout = field_item.kind() + .expect_type() + .layout(ctx) + .expect("Bitfield without layout? Gah!"); let field_type = field_item.to_rust_ty(ctx); let int_type = BlobTyBuilder::new(field_ty_layout).build(); let getter_name = ctx.ext_cx().ident_of(&field_name); - let setter_name = ctx.ext_cx().ident_of(&format!("set_{}", &field_name)); + let setter_name = ctx.ext_cx() + .ident_of(&format!("set_{}", &field_name)); let mask = ((1usize << width) - 1) << offset; // The transmute is unfortunate, but it's needed for enums in // bitfields. @@ -519,18 +541,25 @@ impl<'a> Bitfield<'a> { pub fn $getter_name(&self) -> $field_type { unsafe { ::std::mem::transmute( - ((self.$field_ident & ($mask as $bitfield_type)) >> $offset) - as $int_type) + ( + (self.$field_ident & + ($mask as $bitfield_type)) + >> $offset + ) as $int_type + ) } } #[inline] pub fn $setter_name(&mut self, val: $field_type) { self.$field_ident &= !($mask as $bitfield_type); - self.$field_ident |= (val as $int_type as $bitfield_type << $offset) & ($mask as $bitfield_type); + self.$field_ident |= + (val as $int_type as $bitfield_type << $offset) & + ($mask as $bitfield_type); } } - ).unwrap(); + ) + .unwrap(); let items = match item.unwrap().node { ast::ItemKind::Impl(_, _, _, _, _, items) => items, @@ -555,7 +584,8 @@ impl CodeGenerator for CompInfo { // also don't output template specializations, neither total or partial. // // TODO: Generate layout tests for template specializations, yay! - if self.has_non_type_template_params() || self.is_template_specialization() { + if self.has_non_type_template_params() || + self.is_template_specialization() { return; } @@ -598,19 +628,25 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::derives(&derives)) } - let mut template_args_used = vec![false; applicable_template_args.len()]; + let mut template_args_used = + vec![false; applicable_template_args.len()]; let canonical_name = item.canonical_name(ctx); let builder = if is_union && ctx.options().unstable_rust { - aster::AstBuilder::new().item().pub_() - .with_attrs(attributes) - .union_(&canonical_name) + aster::AstBuilder::new() + .item() + .pub_() + .with_attrs(attributes) + .union_(&canonical_name) } else { - aster::AstBuilder::new().item().pub_() - .with_attrs(attributes) - .struct_(&canonical_name) + aster::AstBuilder::new() + .item() + .pub_() + .with_attrs(attributes) + .struct_(&canonical_name) }; // Generate the vtable from the method list if appropriate. + // // TODO: I don't know how this could play with virtual methods that are // not in the list of methods found by us, we'll see. Also, could the // order of the vtable pointers vary? @@ -623,15 +659,15 @@ impl CodeGenerator for CompInfo { // the parent too. let mut fields = vec![]; if self.needs_explicit_vtable(ctx) { - let vtable = Vtable::new(item.id(), - self.methods(), - self.base_members()); + let vtable = + Vtable::new(item.id(), self.methods(), self.base_members()); vtable.codegen(ctx, result, item); let vtable_type = vtable.to_rust_ty(ctx).to_ptr(true, ctx.span()); - let vtable_field = StructFieldBuilder::named("vtable_").pub_() - .build_ty(vtable_type); + let vtable_field = StructFieldBuilder::named("vtable_") + .pub_() + .build_ty(vtable_type); fields.push(vtable_field); } @@ -649,8 +685,9 @@ impl CodeGenerator for CompInfo { continue; } - for (i, ty) in applicable_template_args.iter().enumerate() { - if base_ty.signature_contains_named_type(ctx, ctx.resolve_type(*ty)) { + for (i, ty_id) in applicable_template_args.iter().enumerate() { + let template_arg_ty = ctx.resolve_type(*ty_id); + if base_ty.signature_contains_named_type(ctx, template_arg_ty) { template_args_used[i] = true; } } @@ -663,7 +700,8 @@ impl CodeGenerator for CompInfo { }; let field = StructFieldBuilder::named(field_name) - .pub_().build_ty(inner); + .pub_() + .build_ty(inner); fields.push(field); } if is_union { @@ -678,11 +716,11 @@ impl CodeGenerator for CompInfo { let mut bitfield_count = 0; let struct_fields = self.fields(); let fields_should_be_private = item.annotations() - .private_fields() - .unwrap_or(false); + .private_fields() + .unwrap_or(false); let struct_accessor_kind = item.annotations() - .accessor_kind() - .unwrap_or(FieldAccessorKind::None); + .accessor_kind() + .unwrap_or(FieldAccessorKind::None); let mut methods = vec![]; let mut anonymous_field_count = 0; @@ -695,15 +733,16 @@ impl CodeGenerator for CompInfo { let field_ty = ctx.resolve_type(field.ty()); // Try to catch a bitfield contination early. - if let (Some(ref mut bitfield_width), Some(width)) = (current_bitfield_width, field.bitfield()) { + if let (Some(ref mut bitfield_width), Some(width)) = + (current_bitfield_width, field.bitfield()) { let layout = current_bitfield_layout.unwrap(); debug!("Testing bitfield continuation {} {} {:?}", *bitfield_width, width, layout); - if *bitfield_width + width <= (layout.size * 8) as u32 { - *bitfield_width += width; - current_bitfield_fields.push(field); - continue; - } + if *bitfield_width + width <= (layout.size * 8) as u32 { + *bitfield_width += width; + current_bitfield_fields.push(field); + continue; + } } // Flush the current bitfield. @@ -721,15 +760,16 @@ impl CodeGenerator for CompInfo { if let Some(width) = field.bitfield() { let layout = field_ty.layout(ctx) - .expect("Bitfield type without layout?"); + .expect("Bitfield type without layout?"); current_bitfield_width = Some(width); current_bitfield_layout = Some(layout); current_bitfield_fields.push(field); continue; } - for (i, ty) in applicable_template_args.iter().enumerate() { - if field_ty.signature_contains_named_type(ctx, ctx.resolve_type(*ty)) { + for (i, ty_id) in applicable_template_args.iter().enumerate() { + let template_arg = ctx.resolve_type(*ty_id); + if field_ty.signature_contains_named_type(ctx, template_arg) { template_args_used[i] = true; } } @@ -756,12 +796,12 @@ impl CodeGenerator for CompInfo { }; let is_private = field.annotations() - .private_fields() - .unwrap_or(fields_should_be_private); + .private_fields() + .unwrap_or(fields_should_be_private); let accessor_kind = field.annotations() - .accessor_kind() - .unwrap_or(struct_accessor_kind); + .accessor_kind() + .unwrap_or(struct_accessor_kind); let mut field = StructFieldBuilder::named(&field_name); @@ -770,7 +810,7 @@ impl CodeGenerator for CompInfo { } let field = field.with_attrs(attrs) - .build_ty(ty.clone()); + .build_ty(ty.clone()); fields.push(field); @@ -811,7 +851,8 @@ impl CodeGenerator for CompInfo { } #[inline] - pub unsafe fn $mutable_getter_name(&mut self) -> &mut $ty { + pub unsafe fn $mutable_getter_name(&mut self) + -> &mut $ty { &mut self.$field_name } } @@ -830,9 +871,10 @@ impl CodeGenerator for CompInfo { }; match accessor_methods_impl.unwrap().node { - ast::ItemKind::Impl(_, _, _, _, _, ref items) - => methods.extend(items.clone()), - _ => unreachable!() + ast::ItemKind::Impl(_, _, _, _, _, ref items) => { + methods.extend(items.clone()) + } + _ => unreachable!(), } } @@ -842,7 +884,8 @@ impl CodeGenerator for CompInfo { // FIXME: May need to pass current_bitfield_layout too. if current_bitfield_width.is_some() { debug_assert!(!current_bitfield_fields.is_empty()); - let bitfield_fields = mem::replace(&mut current_bitfield_fields, vec![]); + let bitfield_fields = mem::replace(&mut current_bitfield_fields, + vec![]); bitfield_count += 1; Bitfield::new(bitfield_count, bitfield_fields) .codegen_fields(ctx, &mut fields, &mut methods); @@ -852,8 +895,9 @@ impl CodeGenerator for CompInfo { if is_union && !ctx.options().unstable_rust { let layout = layout.expect("Unable to get layout information?"); let ty = BlobTyBuilder::new(layout).build(); - let field = StructFieldBuilder::named("bindgen_union_field").pub_() - .build_ty(ty); + let field = StructFieldBuilder::named("bindgen_union_field") + .pub_() + .build_ty(ty); fields.push(field); } @@ -868,8 +912,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 => { @@ -885,8 +931,9 @@ impl CodeGenerator for CompInfo { // may add for unused template parameters. if self.is_unsized(ctx) { 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); } @@ -895,9 +942,12 @@ impl CodeGenerator for CompInfo { if !template_args_used[i] { let name = ctx.resolve_type(*ty).name().unwrap(); let ident = ctx.rust_ident(name); + let phantom = quote_ty!(ctx.ext_cx(), + ::std::marker::PhantomData<$ident>); let field = - StructFieldBuilder::named(format!("_phantom_{}", i)).pub_() - .build_ty(quote_ty!(ctx.ext_cx(), ::std::marker::PhantomData<$ident>)); + StructFieldBuilder::named(format!("_phantom_{}", i)) + .pub_() + .build_ty(phantom); fields.push(field) } } @@ -918,7 +968,8 @@ impl CodeGenerator for CompInfo { let generics = generics.build(); let rust_struct = builder.with_generics(generics.clone()) - .with_fields(fields).build(); + .with_fields(fields) + .build(); result.push(rust_struct); // Generate the inner types and all that stuff. @@ -935,16 +986,18 @@ 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 applicable_template_args.is_empty() && !self.found_unknown_attr() { for var in self.inner_vars() { ctx.resolve_item(*var).codegen(ctx, result, &()); } if let Some(layout) = layout { - let fn_name = - ctx.rust_ident_raw(&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 ident = ctx.rust_ident_raw(&canonical_name); let size_of_expr = quote_expr!(ctx.ext_cx(), ::std::mem::size_of::<$ident>()); @@ -957,19 +1010,25 @@ impl CodeGenerator for CompInfo { fn $fn_name() { assert_eq!($size_of_expr, $size); assert_eq!($align_of_expr, $align); - }).unwrap(); + }) + .unwrap(); result.push(item); } let mut method_names = Default::default(); for method in self.methods() { - method.codegen_method(ctx, &mut methods, &mut method_names, result, item); + method.codegen_method(ctx, + &mut methods, + &mut method_names, + result, + item); } } // NB: We can't use to_rust_ty here since for opaque types this tries to // use the specialization knowledge to generate a blob field. - let ty_for_impl = aster::AstBuilder::new().ty().path().id(&canonical_name).build(); + let ty_for_impl = + aster::AstBuilder::new().ty().path().id(&canonical_name).build(); if needs_clone_impl { let impl_ = quote_item!(ctx.ext_cx(), impl X { @@ -982,22 +1041,26 @@ impl CodeGenerator for CompInfo { _ => unreachable!(), }; - let clone_impl = - aster::AstBuilder::new().item().impl_() - .trait_().id("Clone").build() - .with_generics(generics.clone()) - .with_items(impl_) - .build_ty(ty_for_impl.clone()); + let clone_impl = aster::AstBuilder::new() + .item() + .impl_() + .trait_() + .id("Clone") + .build() + .with_generics(generics.clone()) + .with_items(impl_) + .build_ty(ty_for_impl.clone()); result.push(clone_impl); } if !methods.is_empty() { - let methods = - aster::AstBuilder::new().item().impl_() - .with_generics(generics) - .with_items(methods) - .build_ty(ty_for_impl); + let methods = aster::AstBuilder::new() + .item() + .impl_() + .with_generics(generics) + .with_items(methods) + .build_ty(ty_for_impl); result.push(methods); } } @@ -1040,7 +1103,7 @@ impl MethodCodegen for Method { let count = { let mut count = method_names.entry(name.clone()) - .or_insert(0); + .or_insert(0); *count += 1; *count - 1 }; @@ -1050,7 +1113,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() { let mutability = if self.is_const() { ast::Mutability::Immutable @@ -1059,6 +1123,7 @@ impl MethodCodegen for Method { }; assert!(!fndecl.inputs.is_empty()); + // FIXME: use aster here. fndecl.inputs[0] = ast::Arg { ty: P(ast::Ty { @@ -1075,9 +1140,11 @@ impl MethodCodegen for Method { }), pat: P(ast::Pat { id: ast::DUMMY_NODE_ID, - node: ast::PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable), - respan(ctx.span(), ctx.ext_cx().ident_of("self")), - None), + node: ast::PatKind::Ident( + ast::BindingMode::ByValue(ast::Mutability::Immutable), + respan(ctx.span(), ctx.ext_cx().ident_of("self")), + None + ), span: ctx.span(), }), id: ast::DUMMY_NODE_ID, @@ -1095,16 +1162,19 @@ impl MethodCodegen for Method { // TODO: We need to keep in sync the argument names, so we should unify // this with the other loop that decides them. let mut unnamed_arguments = 0; - let mut exprs = signature.argument_types().iter().map(|&(ref name, _ty)| { - let arg_name = match *name { - Some(ref name) => ctx.rust_mangle(name).into_owned(), - None => { - unnamed_arguments += 1; - format!("arg{}", unnamed_arguments) - } - }; - aster::expr::ExprBuilder::new().id(arg_name) - }).collect::>(); + let mut exprs = signature.argument_types() + .iter() + .map(|&(ref name, _ty)| { + let arg_name = match *name { + Some(ref name) => ctx.rust_mangle(name).into_owned(), + None => { + unnamed_arguments += 1; + format!("arg{}", unnamed_arguments) + } + }; + aster::expr::ExprBuilder::new().id(arg_name) + }) + .collect::>(); if !self.is_static() { assert!(!exprs.is_empty()); @@ -1115,10 +1185,11 @@ impl MethodCodegen for Method { }; }; - let call = aster::expr::ExprBuilder::new().call() - .id(function_name) - .with_args(exprs) - .build(); + let call = aster::expr::ExprBuilder::new() + .call() + .id(function_name) + .with_args(exprs) + .build(); let block = ast::Block { stmts: vec![ @@ -1164,12 +1235,15 @@ 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 } }; @@ -1203,8 +1277,12 @@ impl CodeGenerator for Enum { builder = builder.with_attr(attributes::doc(comment)); } - 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); @@ -1213,8 +1291,8 @@ impl CodeGenerator for Enum { fn add_constant(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. + // 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, @@ -1225,11 +1303,15 @@ impl CodeGenerator for Enum { variant_name.into() }; - let constant = aster::AstBuilder::new().item().pub_() - .const_(constant_name) - .expr().path() - .ids(&[&*enum_canonical_name, referenced_name]) - .build().build(enum_rust_ty); + let constant = aster::AstBuilder::new() + .item() + .pub_() + .const_(constant_name) + .expr() + .path() + .ids(&[&*enum_canonical_name, referenced_name]) + .build() + .build(enum_rust_ty); result.push(constant); } @@ -1245,8 +1327,11 @@ impl CodeGenerator for Enum { Entry::Occupied(ref entry) => { let existing_variant_name = entry.get(); let variant_name = ctx.rust_mangle(variant.name()); - add_constant(enum_ty, &name, &*variant_name, - existing_variant_name, enum_rust_ty.clone(), + add_constant(enum_ty, + &name, + &*variant_name, + existing_variant_name, + enum_rust_ty.clone(), result); } Entry::Vacant(entry) => { @@ -1272,16 +1357,22 @@ impl CodeGenerator for Enum { variant_name.clone() } else { if parent_canonical_name.is_none() { - parent_canonical_name = Some(item.parent_id().canonical_name(ctx)); + parent_canonical_name = Some(item.parent_id() + .canonical_name(ctx)); } + let parent_name = parent_canonical_name.as_ref() + .unwrap(); + Cow::Owned( - format!("{}_{}", parent_canonical_name.as_ref().unwrap(), - variant_name)) + format!("{}_{}", parent_name, variant_name)) }; - add_constant(enum_ty, &name, &mangled_name, - &variant_name, enum_rust_ty.clone(), + add_constant(enum_ty, + &name, + &mangled_name, + &variant_name, + enum_rust_ty.clone(), result); } @@ -1298,7 +1389,10 @@ impl CodeGenerator for Enum { trait ToRustTy { type Extra; - fn to_rust_ty(&self, ctx: &BindgenContext, extra: &Self::Extra) -> P; + fn to_rust_ty(&self, + ctx: &BindgenContext, + extra: &Self::Extra) + -> P; } trait ItemToRustTy { @@ -1336,7 +1430,9 @@ impl ToRustTy for Type { TypeKind::Void => raw!(c_void), // TODO: we should do something smart with nullptr, or maybe *const // c_void is enough? - TypeKind::NullPtr => quote_ty!(ctx.ext_cx(), *const ::std::os::raw::c_void), + TypeKind::NullPtr => { + quote_ty!(ctx.ext_cx(), *const ::std::os::raw::c_void) + } TypeKind::Int(ik) => { match ik { IntKind::Bool => aster::ty::TyBuilder::new().bool(), @@ -1355,8 +1451,9 @@ impl ToRustTy for Type { // FIXME: This doesn't generate the proper alignment, but we // can't do better right now. We should be able to use // i128/u128 when they're available. - IntKind::U128 | - IntKind::I128 => aster::ty::TyBuilder::new().array(2).u64(), + IntKind::U128 | IntKind::I128 => { + aster::ty::TyBuilder::new().array(2).u64() + } } } TypeKind::Float(fk) => { @@ -1365,8 +1462,9 @@ impl ToRustTy for Type { // account? match fk { FloatKind::Float => aster::ty::TyBuilder::new().f32(), - FloatKind::Double | - FloatKind::LongDouble => aster::ty::TyBuilder::new().f64(), + FloatKind::Double | FloatKind::LongDouble => { + aster::ty::TyBuilder::new().f64() + } } } TypeKind::Function(ref fs) => { @@ -1387,13 +1485,15 @@ impl ToRustTy for Type { let mut inner_ty = inner.to_rust_ty(ctx).unwrap(); if let ast::TyKind::Path(_, ref mut path) = inner_ty.node { + let template_args = template_args.iter() + .map(|arg| arg.to_rust_ty(ctx)) + .collect(); + path.segments.last_mut().unwrap().parameters = ast::PathParameters::AngleBracketed( ast::AngleBracketedParameterData { lifetimes: vec![], - types: P::from_vec(template_args.iter().map(|arg| { - arg.to_rust_ty(ctx) - }).collect()), + types: P::from_vec(template_args), bindings: P::from_vec(vec![]), } ); @@ -1407,7 +1507,9 @@ impl ToRustTy for Type { // Pray if there's no available layout. let layout = self.layout(ctx).unwrap_or_else(Layout::zero); BlobTyBuilder::new(layout).build() - } else if let Some(ty) = utils::type_from_named(ctx, spelling, inner) { + } else if let Some(ty) = utils::type_from_named(ctx, + spelling, + inner) { ty } else { utils::build_templated_path(item, ctx, true) @@ -1416,22 +1518,23 @@ impl ToRustTy for Type { TypeKind::Comp(ref info) => { if item.is_opaque(ctx) || info.has_non_type_template_params() { return match self.layout(ctx) { - Some(layout) => { - BlobTyBuilder::new(layout).build() - } + Some(layout) => BlobTyBuilder::new(layout).build(), None => { warn!("Couldn't compute layout for a type with non \ - type template params or opaque, expect dragons!"); + type template params or opaque, expect \ + dragons!"); aster::AstBuilder::new().ty().unit() } - } + }; } utils::build_templated_path(item, ctx, false) } TypeKind::BlockPointer => { let void = raw!(c_void); - void.to_ptr(/* is_const = */ false, ctx.span()) + void.to_ptr(/* is_const = */ + false, + ctx.span()) } TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { @@ -1444,7 +1547,8 @@ impl ToRustTy for Type { if inner_ty.canonical_type(ctx).is_function() { ty } else { - let is_const = self.is_const() || inner.expect_type().is_const(); + let is_const = self.is_const() || + inner.expect_type().is_const(); ty.to_ptr(is_const, ctx.span()) } } @@ -1453,8 +1557,9 @@ impl ToRustTy for Type { let ident = ctx.rust_ident(&name); quote_ty!(ctx.ext_cx(), $ident) } - ref u @ TypeKind::UnresolvedTypeRef(..) - => unreachable!("Should have been resolved after parsing {:?}!", u), + ref u @ TypeKind::UnresolvedTypeRef(..) => { + unreachable!("Should have been resolved after parsing {:?}!", u) + } } } } @@ -1465,22 +1570,26 @@ impl ToRustTy for FunctionSig { fn to_rust_ty(&self, ctx: &BindgenContext, _item: &Item) -> P { // TODO: we might want to consider ignoring the reference return value. let return_item = ctx.resolve_item(self.return_type()); - let ret = if let TypeKind::Void = *return_item.kind().expect_type().kind() { - ast::FunctionRetTy::Default(ctx.span()) - } else { - ast::FunctionRetTy::Ty(return_item.to_rust_ty(ctx)) - }; + let ret = + if let TypeKind::Void = *return_item.kind().expect_type().kind() { + ast::FunctionRetTy::Default(ctx.span()) + } else { + ast::FunctionRetTy::Ty(return_item.to_rust_ty(ctx)) + }; let mut unnamed_arguments = 0; let arguments = self.argument_types().iter().map(|&(ref name, ty)| { let arg_item = ctx.resolve_item(ty); let arg_ty = arg_item.kind().expect_type(); - // From the C90 standard (http://c0x.coding-guidelines.com/6.7.5.3.html) - // 1598 - A declaration of a parameter as “array of type” shall be - // adjusted to “qualified pointer to type”, where the type qualifiers - // (if any) are those specified within the [ and ] of the array type - // derivation. + // From the C90 standard[1]: + // + // A declaration of a parameter as "array of type" shall be + // adjusted to "qualified pointer to type", where the type + // qualifiers (if any) are those specified within the [ and ] of + // the array type derivation. + // + // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html let arg_ty = if let TypeKind::Array(t, _) = *arg_ty.kind() { t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span()) } else { @@ -1566,15 +1675,14 @@ impl CodeGenerator for Function { let foreign_item_kind = ast::ForeignItemKind::Fn(fndecl, ast::Generics::default()); - let foreign_item = - ast::ForeignItem { - ident: ctx.rust_ident_raw(&canonical_name), - attrs: attributes, - node: foreign_item_kind, - id: ast::DUMMY_NODE_ID, - span: ctx.span(), - vis: ast::Visibility::Public, - }; + let foreign_item = ast::ForeignItem { + ident: ctx.rust_ident_raw(&canonical_name), + attrs: attributes, + node: foreign_item_kind, + id: ast::DUMMY_NODE_ID, + span: ctx.span(), + vis: ast::Visibility::Public, + }; let item = ForeignModBuilder::new(signature.abi()) .with_foreign_item(foreign_item) @@ -1596,8 +1704,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { context.options().whitelisted_functions.is_empty() && context.options().whitelisted_vars.is_empty() { for (_item_id, item) in context.items() { - // Non-toplevel item parents are the responsible one for generating - // them. + // Non-toplevel item parents are the responsible one for + // generating them. if item.is_toplevel(context) { item.codegen(context, &mut result, &()); } @@ -1629,17 +1737,24 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { if let TypeKind::Enum(ref enum_) = *ty.kind() { if ty.name().is_none() { if enum_.variants().iter().any(|variant| { - context.options().whitelisted_vars.matches(&variant.name()) + context.options() + .whitelisted_vars + .matches(&variant.name()) }) { - item.collect_types(context, &mut items, &()); + item.collect_types(context, + &mut items, + &()); } } } } ItemKind::Function(ref fun) => { - if context.options().whitelisted_functions.matches(&name) { + if context.options() + .whitelisted_functions + .matches(&name) { items.insert(item.id()); - fun.signature().collect_types(context, &mut items, &()); + fun.signature() + .collect_types(context, &mut items, &()); } } ItemKind::Var(ref var) => { @@ -1652,7 +1767,10 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { } } - fn contains_parent(ctx: &BindgenContext, types: &ItemSet, id: ItemId) -> bool { + fn contains_parent(ctx: &BindgenContext, + types: &ItemSet, + id: ItemId) + -> bool { let item = ctx.resolve_item(id); let mut last = id; let mut current = item.parent_id(); @@ -1670,7 +1788,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { for item_id in items.iter() { let item = context.resolve_item(*item_id); - if item.is_toplevel(context) || !contains_parent(context, &items, *item_id) { + if item.is_toplevel(context) || + !contains_parent(context, &items, *item_id) { item.codegen(context, &mut result, &()); } } @@ -1685,21 +1804,23 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { } mod utils { + use aster; use ir::context::BindgenContext; use ir::item::{Item, ItemCanonicalPath, ItemId}; use ir::ty::TypeKind; - use syntax::ast; - use syntax::ptr::P; use std::mem; use super::ItemToRustTy; - use aster; + use syntax::ast; + use syntax::ptr::P; - pub fn prepend_union_types(ctx: &BindgenContext, result: &mut Vec>) { + pub fn prepend_union_types(ctx: &BindgenContext, + result: &mut Vec>) { let union_field_decl = quote_item!(ctx.ext_cx(), #[derive(Debug)] #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); - ).unwrap(); + ) + .unwrap(); let union_field_impl = quote_item!(&ctx.ext_cx(), impl __BindgenUnionField { @@ -1718,7 +1839,8 @@ mod utils { ::std::mem::transmute(self) } } - ).unwrap(); + ) + .unwrap(); let union_field_default_impl = quote_item!(&ctx.ext_cx(), impl ::std::default::Default for __BindgenUnionField { @@ -1727,7 +1849,8 @@ mod utils { Self::new() } } - ).unwrap(); + ) + .unwrap(); let union_field_clone_impl = quote_item!(&ctx.ext_cx(), impl ::std::clone::Clone for __BindgenUnionField { @@ -1736,11 +1859,13 @@ mod utils { Self::new() } } - ).unwrap(); + ) + .unwrap(); let union_field_copy_impl = quote_item!(&ctx.ext_cx(), impl ::std::marker::Copy for __BindgenUnionField {} - ).unwrap(); + ) + .unwrap(); let items = vec![ union_field_decl, union_field_impl, @@ -1754,26 +1879,32 @@ mod utils { } - pub fn build_templated_path(item: &Item, ctx: &BindgenContext, only_named: bool) -> P { + pub fn build_templated_path(item: &Item, + ctx: &BindgenContext, + only_named: bool) + -> P { let path = item.canonical_path(ctx); let builder = aster::AstBuilder::new().ty().path(); let template_args = if only_named { - item.applicable_template_args(ctx).iter().filter(|arg| { - ctx.resolve_type(**arg).is_named() - }).map(|arg| { - arg.to_rust_ty(ctx) - }).collect::>() + item.applicable_template_args(ctx) + .iter() + .filter(|arg| ctx.resolve_type(**arg).is_named()) + .map(|arg| arg.to_rust_ty(ctx)) + .collect::>() } else { - item.applicable_template_args(ctx).iter().map(|arg| { - arg.to_rust_ty(ctx) - }).collect::>() + item.applicable_template_args(ctx) + .iter() + .map(|arg| arg.to_rust_ty(ctx)) + .collect::>() }; // XXX: I suck at aster. if path.len() == 1 { return builder.segment(&path[0]) - .with_tys(template_args).build().build(); + .with_tys(template_args) + .build() + .build(); } let mut builder = builder.id(&path[0]); @@ -1782,7 +1913,8 @@ mod utils { builder = if i == path.len() - 2 { // XXX Extra clone courtesy of the borrow checker. builder.segment(&segment) - .with_tys(template_args.clone()).build() + .with_tys(template_args.clone()) + .build() } else { builder.segment(&segment).build() } @@ -1798,7 +1930,8 @@ mod utils { pub fn type_from_named(ctx: &BindgenContext, name: &str, - _inner: ItemId) -> Option> { + _inner: ItemId) + -> Option> { // FIXME: We could use the inner item to check this is really a // primitive type but, who the heck overrides these anyway? macro_rules! ty { @@ -1816,17 +1949,16 @@ mod utils { "int64_t" => ty!(i64), "uint64_t" => ty!(u64), - "uintptr_t" | - "size_t" => ty!(usize), + "uintptr_t" | "size_t" => ty!(usize), - "intptr_t" | - "ptrdiff_t" | - "ssize_t" => ty!(isize), + "intptr_t" | "ptrdiff_t" | "ssize_t" => ty!(isize), _ => return None, }) } - pub fn rust_fndecl_from_signature(ctx: &BindgenContext, sig: &Item) -> P { + pub fn rust_fndecl_from_signature(ctx: &BindgenContext, + sig: &Item) + -> P { use codegen::ToRustTy; let signature = sig.kind().expect_type(); diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs index 0ceb676d31..58308d6dde 100644 --- a/src/ir/annotations.rs +++ b/src/ir/annotations.rs @@ -58,7 +58,7 @@ impl Default for Annotations { use_instead_of: None, disallow_copy: false, private_fields: None, - accessor_kind: None + accessor_kind: None, } } } @@ -71,11 +71,7 @@ impl Annotations { let mut matched_one = false; anno.parse(&cursor.comment(), &mut matched_one); - if matched_one { - Some(anno) - } else { - None - } + if matched_one { Some(anno) } else { None } } /// Should this type be hidden? @@ -133,7 +129,9 @@ impl Annotations { use clangll::CXComment_HTMLStartTag; if comment.kind() == CXComment_HTMLStartTag && comment.get_tag_name() == "div" && - comment.get_tag_attrs().next().map_or(false, |attr| attr.name == "rustbindgen") { + comment.get_tag_attrs() + .next() + .map_or(false, |attr| attr.name == "rustbindgen") { *matched = true; for attr in comment.get_tag_attrs() { match attr.name.as_str() { @@ -141,10 +139,13 @@ impl Annotations { "hide" => self.hide = true, "nocopy" => self.disallow_copy = true, "replaces" => self.use_instead_of = Some(attr.value), - "private" => self.private_fields = Some(attr.value != "false"), - "accessor" - => self.accessor_kind = Some(parse_accessor(&attr.value)), - _ => {}, + "private" => { + self.private_fields = Some(attr.value != "false") + } + "accessor" => { + self.accessor_kind = Some(parse_accessor(&attr.value)) + } + _ => {} } } } diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 98003936b5..d55c24ca16 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1,15 +1,15 @@ //! Compound types (unions and structs) in our intermediate representation. +use clang; +use parse::{ClangItemParser, ParseError}; +use std::cell::Cell; +use std::cmp; use super::annotations::Annotations; use super::context::BindgenContext; -use super::layout::Layout; use super::item::{Item, ItemId}; -use super::ty::{Type, RUST_DERIVE_IN_ARRAY_LIMIT}; +use super::layout::Layout; +use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type}; use super::type_collector::{ItemSet, TypeCollector}; -use std::cell::Cell; -use std::cmp; -use parse::{ClangItemParser, ParseError}; -use clang; /// The kind of compound type. #[derive(Debug, Copy, Clone, PartialEq)] @@ -103,7 +103,8 @@ impl Field { comment: Option, annotations: Option, bitfield: Option, - mutable: bool) -> Field { + mutable: bool) + -> Field { Field { name: name, ty: ty, @@ -199,7 +200,8 @@ pub struct CompInfo { /// TODO: We should be able to compute this. has_nonempty_base: bool, - /// If this type has a template parameter which is not a type (e.g.: a size_t) + /// If this type has a template parameter which is not a type (e.g.: a + /// size_t) has_non_type_template_params: bool, /// Whether this struct layout is packed. @@ -250,7 +252,10 @@ impl CompInfo { } /// Can we derive the `Debug` trait for this compound type? - pub fn can_derive_debug(&self, ctx: &BindgenContext, layout: Option) -> bool { + pub fn can_derive_debug(&self, + ctx: &BindgenContext, + layout: Option) + -> bool { // We can reach here recursively via template parameters of a member, // for example. if self.detect_derive_debug_cycle.get() { @@ -258,7 +263,7 @@ impl CompInfo { return true; } - if self.kind == CompKind::Union { + if self.kind == CompKind::Union { if ctx.options().unstable_rust { return false; } @@ -270,23 +275,20 @@ impl CompInfo { self.detect_derive_debug_cycle.set(true); - let can_derive_debug = - self.base_members.iter().all(|ty| { - ctx.resolve_type(*ty) - .can_derive_debug(ctx) - }) && - self.template_args.iter().all(|ty| { - ctx.resolve_type(*ty) - .can_derive_debug(ctx) - }) && - self.fields.iter().all(|field| { - ctx.resolve_type(field.ty) - .can_derive_debug(ctx) - }) && + let can_derive_debug = { + self.base_members + .iter() + .all(|ty| ctx.resolve_type(*ty).can_derive_debug(ctx)) && + self.template_args + .iter() + .all(|ty| ctx.resolve_type(*ty).can_derive_debug(ctx)) && + self.fields + .iter() + .all(|f| ctx.resolve_type(f.ty).can_derive_debug(ctx)) && self.ref_template.map_or(true, |template| { - ctx.resolve_type(template) - .can_derive_debug(ctx) - }); + ctx.resolve_type(template).can_derive_debug(ctx) + }) + }; self.detect_derive_debug_cycle.set(false); @@ -296,15 +298,11 @@ impl CompInfo { /// Is this compound type unsized? pub fn is_unsized(&self, ctx: &BindgenContext) -> bool { !self.has_vtable(ctx) && self.fields.is_empty() && - self.base_members.iter().all(|base| { - ctx - .resolve_type(*base) - .canonical_type(ctx) - .is_unsized(ctx) - }) && - self.ref_template.map_or(true, |template| { - ctx.resolve_type(template).is_unsized(ctx) - }) + self.base_members.iter().all(|base| { + ctx.resolve_type(*base).canonical_type(ctx).is_unsized(ctx) + }) && + self.ref_template + .map_or(true, |template| ctx.resolve_type(template).is_unsized(ctx)) } /// Does this compound type have a destructor? @@ -317,7 +315,8 @@ impl CompInfo { self.detect_has_destructor_cycle.set(true); - let has_destructor = self.has_destructor || match self.kind { + let has_destructor = self.has_destructor || + match self.kind { CompKind::Union => false, CompKind::Struct => { // NB: We can't rely on a type with type parameters @@ -327,15 +326,15 @@ impl CompInfo { self.ref_template.as_ref().map_or(false, |t| { ctx.resolve_type(*t).has_destructor(ctx) }) || - self.template_args.iter().any(|t| { - ctx.resolve_type(*t).has_destructor(ctx) - }) || - self.base_members.iter().any(|t| { - ctx.resolve_type(*t).has_destructor(ctx) - }) || + self.template_args + .iter() + .any(|t| ctx.resolve_type(*t).has_destructor(ctx)) || + self.base_members + .iter() + .any(|t| ctx.resolve_type(*t).has_destructor(ctx)) || self.fields.iter().any(|field| { ctx.resolve_type(field.ty) - .has_destructor(ctx) + .has_destructor(ctx) }) } }; @@ -360,24 +359,23 @@ impl CompInfo { } // https://github.com/rust-lang/rust/issues/36640 - if !self.template_args.is_empty() || - self.ref_template.is_some() || - !item.applicable_template_args(ctx).is_empty() { + if !self.template_args.is_empty() || self.ref_template.is_some() || + !item.applicable_template_args(ctx).is_empty() { return false; } } // With template args, use a safe subset of the types, // since copyability depends on the types itself. - self.ref_template.as_ref().map_or(true, |t| { - ctx.resolve_item(*t).can_derive_copy(ctx) - }) && - self.base_members.iter().all(|t| { - ctx.resolve_item(*t).can_derive_copy(ctx) - }) && + self.ref_template + .as_ref() + .map_or(true, |t| ctx.resolve_item(*t).can_derive_copy(ctx)) && + self.base_members + .iter() + .all(|t| ctx.resolve_item(*t).can_derive_copy(ctx)) && self.fields.iter().all(|field| { ctx.resolve_item(field.ty) - .can_derive_copy(ctx) + .can_derive_copy(ctx) }) } @@ -411,7 +409,7 @@ impl CompInfo { let mut max_align = 0; for field in &self.fields { let field_layout = ctx.resolve_type(field.ty) - .layout(ctx); + .layout(ctx); if let Some(layout) = field_layout { max_size = cmp::max(max_size, layout.size); @@ -441,11 +439,12 @@ impl CompInfo { /// Does this type have a virtual table? pub fn has_vtable(&self, ctx: &BindgenContext) -> bool { - self.has_vtable || self.base_members().iter().any(|base| { - ctx - .resolve_type(*base) + self.has_vtable || + self.base_members().iter().any(|base| { + ctx.resolve_type(*base) .has_vtable(ctx) - }) || self.ref_template.map_or(false, |template| { + }) || + self.ref_template.map_or(false, |template| { ctx.resolve_type(template).has_vtable(ctx) }) } @@ -469,7 +468,8 @@ impl CompInfo { pub fn from_ty(potential_id: ItemId, ty: &clang::Type, location: Option, - ctx: &mut BindgenContext) -> Result { + ctx: &mut BindgenContext) + -> Result { use clangll::*; // Sigh... For class templates we want the location, for // specialisations, we want the declaration... So just try both. @@ -491,14 +491,15 @@ impl CompInfo { let mut ci = CompInfo::new(kind); ci.is_anonymous = cursor.is_anonymous(); ci.template_args = match ty.template_args() { - // In forward declarations and not specializations, etc, they are in - // the ast, we'll meet them in CXCursor_TemplateTypeParameter + // In forward declarations and not specializations, + // etc, they are in + // the ast, we'll meet them in + // CXCursor_TemplateTypeParameter None => vec![], Some(arg_types) => { let num_arg_types = arg_types.len(); - let args = arg_types - .filter(|t| t.kind() != CXType_Invalid) + let args = arg_types.filter(|t| t.kind() != CXType_Invalid) .map(|t| Item::from_ty_or_ref(t, None, None, ctx)) .collect::>(); @@ -516,7 +517,7 @@ impl CompInfo { let mut maybe_anonymous_struct_field = None; cursor.visit(|cur, _other| { if cur.kind() != CXCursor_FieldDecl { - if let Some((ty, ref _clang_ty)) = maybe_anonymous_struct_field { + if let Some((ty, _)) = maybe_anonymous_struct_field { let field = Field::new(None, ty, None, None, None, false); ci.fields.push(field); } @@ -535,16 +536,24 @@ impl CompInfo { CXChildVisit_Continue }); if !used { - let field = Field::new(None, ty, None, None, None, false); + let field = Field::new(None, + ty, + None, + None, + None, + false); ci.fields.push(field); } - }, + } None => {} } let bit_width = cur.bit_width(); - let field_type = - Item::from_ty_or_ref(cur.cur_type(), Some(*cur), Some(potential_id), ctx); + let field_type = Item::from_ty_or_ref(cur.cur_type(), + Some(*cur), + Some(potential_id), + ctx); + let comment = cur.raw_comment(); let annotations = Annotations::new(cur); let name = cur.spelling(); @@ -557,8 +566,12 @@ impl CompInfo { let name = if name.is_empty() { None } else { Some(name) }; - let field = Field::new(name, field_type, comment, - annotations, bit_width, is_mutable); + let field = Field::new(name, + field_type, + comment, + annotations, + bit_width, + is_mutable); ci.fields.push(field); // No we look for things like attributes and stuff. @@ -581,14 +594,16 @@ impl CompInfo { CXCursor_ClassTemplate | CXCursor_ClassDecl => { let inner = Item::parse(*cur, Some(potential_id), ctx) - .expect("Inner ClassDecl"); + .expect("Inner ClassDecl"); if !ci.inner_types.contains(&inner) { ci.inner_types.push(inner); } // A declaration of an union or a struct without name could // also be an unnamed field, unfortunately. - if cur.spelling().is_empty() && cur.kind() != CXCursor_EnumDecl { - maybe_anonymous_struct_field = Some((inner, cur.cur_type())); + if cur.spelling().is_empty() && + cur.kind() != CXCursor_EnumDecl { + let ty = cur.cur_type(); + maybe_anonymous_struct_field = Some((inner, ty)); } } CXCursor_PackedAttr => { @@ -603,18 +618,24 @@ impl CompInfo { return CXChildVisit_Continue; } - let default_type = - Item::from_ty(&cur.cur_type(), Some(*cur), Some(potential_id), ctx).ok(); - let param = Item::named_type(cur.spelling(), default_type, - potential_id, ctx); + let default_type = Item::from_ty(&cur.cur_type(), + Some(*cur), + Some(potential_id), + ctx) + .ok(); + let param = Item::named_type(cur.spelling(), + default_type, + potential_id, + ctx); ci.template_args.push(param); } CXCursor_CXXBaseSpecifier => { if !ci.has_vtable { ci.has_vtable = cur.is_virtual_base(); } - let type_id = Item::from_ty(&cur.cur_type(), None, None, ctx) - .expect("BaseSpecifier"); + let type_id = + Item::from_ty(&cur.cur_type(), None, None, ctx) + .expect("BaseSpecifier"); ci.base_members.push(type_id); } CXCursor_CXXMethod => { @@ -663,9 +684,12 @@ impl CompInfo { return CXChildVisit_Continue; } - // NB: This gets us an owned `Function`, not a `FunctionSig`. - let method_signature = Item::parse(*cur, Some(potential_id), ctx) - .expect("CXXMethod"); + // NB: This gets us an owned `Function`, not a + // `FunctionSig`. + let method_signature = + Item::parse(*cur, Some(potential_id), ctx) + .expect("CXXMethod"); + let is_const = cur.method_is_const(); let method_kind = if is_static { MethodKind::Static @@ -674,7 +698,11 @@ impl CompInfo { } else { MethodKind::Normal }; - ci.methods.push(Method::new(method_kind, method_signature, is_const)); + + let method = + Method::new(method_kind, method_signature, is_const); + + ci.methods.push(method); } CXCursor_Destructor => { if cur.method_is_virtual() { @@ -688,7 +716,8 @@ impl CompInfo { } CXCursor_VarDecl => { let linkage = cur.linkage(); - if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { + if linkage != CXLinkage_External && + linkage != CXLinkage_UniqueExternal { return CXChildVisit_Continue; } @@ -698,7 +727,7 @@ impl CompInfo { } let item = Item::parse(*cur, Some(potential_id), ctx) - .expect("VarDecl"); + .expect("VarDecl"); ci.inner_vars.push(item); } // Intentionally not handled @@ -708,8 +737,10 @@ impl CompInfo { CXCursor_FunctionTemplate | CXCursor_ConversionFunction => {} _ => { - warn!("unhandled composite member `{}` (kind {}) in `{}` ({})", - cur.spelling(), cur.kind(), cursor.spelling(), + warn!("unhandled comp member `{}` (kind {}) in `{}` ({})", + cur.spelling(), + cur.kind(), + cursor.spelling(), cur.location()); } } @@ -724,7 +755,8 @@ impl CompInfo { Ok(ci) } - fn kind_from_cursor(cursor: &clang::Cursor) -> Result { + fn kind_from_cursor(cursor: &clang::Cursor) + -> Result { use clangll::*; Ok(match cursor.kind() { CXCursor_UnionDecl => CompKind::Union, @@ -750,7 +782,8 @@ impl CompInfo { /// See also documentation for `ir::Item::signature_contains_named_type`. pub fn signature_contains_named_type(&self, ctx: &BindgenContext, - ty: &Type) -> bool { + ty: &Type) + -> bool { // We don't generate these, so rather don't make the codegen step to // think we got it covered. if self.has_non_type_template_params() { @@ -758,7 +791,7 @@ impl CompInfo { } self.template_args.iter().any(|arg| { ctx.resolve_type(*arg) - .signature_contains_named_type(ctx, ty) + .signature_contains_named_type(ctx, ty) }) } @@ -787,19 +820,18 @@ impl CompInfo { /// Returns whether this type needs an explicit vtable because it has /// virtual methods and none of its base classes has already a vtable. pub fn needs_explicit_vtable(&self, ctx: &BindgenContext) -> bool { - self.has_vtable(ctx) && !self.base_members.iter().any(|base| { + self.has_vtable(ctx) && + !self.base_members.iter().any(|base| { // NB: Ideally, we could rely in all these types being `comp`, and // life would be beautiful. // // Unfortunately, given the way we implement --match-pat, and also // that you can inherit from templated types, we need to handle // other cases here too. - ctx - .resolve_type(*base) + ctx.resolve_type(*base) .canonical_type(ctx) - .as_comp().map_or(false, |ci| { - ci.has_vtable(ctx) - }) + .as_comp() + .map_or(false, |ci| ci.has_vtable(ctx)) }) } } diff --git a/src/ir/context.rs b/src/ir/context.rs index 729a1c02b5..273dc3e319 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1,20 +1,20 @@ //! Common context that is passed around during parsing and codegen. -use super::ty::{Type, TypeKind, FloatKind}; -use super::item::{Item, ItemCanonicalName, ItemId}; -use super::item_kind::ItemKind; -use super::int::IntKind; -use super::module::Module; +use BindgenOptions; use clang::{self, Cursor}; -use std::borrow::{Cow, Borrow}; +use parse::ClangItemParser; +use std::borrow::{Borrow, Cow}; +use std::collections::{HashMap, HashSet}; use std::collections::btree_map::{self, BTreeMap}; -use std::collections::{HashSet, HashMap}; use std::fmt; +use super::int::IntKind; +use super::item::{Item, ItemCanonicalName, ItemId}; +use super::item_kind::ItemKind; +use super::module::Module; +use super::ty::{FloatKind, Type, TypeKind}; use syntax::ast::Ident; use syntax::codemap::{DUMMY_SP, Span}; use syntax::ext::base::ExtCtxt; -use parse::ClangItemParser; -use BindgenOptions; /// A key used to index a resolved type, so we only process it once. /// @@ -105,10 +105,15 @@ impl<'ctx> BindgenContext<'ctx> { let index = clang::Index::new(false, true); + let parse_options = + clangll::CXTranslationUnit_DetailedPreprocessingRecord; let translation_unit = - clang::TranslationUnit::parse(&index, "", &options.clang_args, &[], - clangll::CXTranslationUnit_DetailedPreprocessingRecord) - .expect("null TranslationUnit received from `clang::TranslationUnit::parse`"); + clang::TranslationUnit::parse(&index, + "", + &options.clang_args, + &[], + parse_options) + .expect("TranslationUnit::parse"); let root_module = Self::build_root_module(); let mut me = BindgenContext { @@ -141,8 +146,12 @@ impl<'ctx> BindgenContext<'ctx> { item: Item, declaration: Option, location: Option) { - use clangll::{CXCursor_ClassTemplate, CXCursor_ClassTemplatePartialSpecialization}; - debug!("BindgenContext::add_item({:?}, declaration: {:?}, loc: {:?}", item, declaration, location); + use clangll::{CXCursor_ClassTemplate, + CXCursor_ClassTemplatePartialSpecialization}; + debug!("BindgenContext::add_item({:?}, declaration: {:?}, loc: {:?}", + item, + declaration, + location); debug_assert!(declaration.is_some() || !item.kind().is_type() || item.kind().expect_type().is_builtin_or_named(), "Adding a type without declaration?"); @@ -161,7 +170,8 @@ impl<'ctx> BindgenContext<'ctx> { if !declaration.is_valid() { if let Some(location) = location { if location.kind() == CXCursor_ClassTemplate || - location.kind() == CXCursor_ClassTemplatePartialSpecialization { + location.kind() == + CXCursor_ClassTemplatePartialSpecialization { declaration = location; } } @@ -174,7 +184,8 @@ impl<'ctx> BindgenContext<'ctx> { // Fortunately, we don't care about those types being // duplicated, so we can just ignore them. debug!("Invalid declaration {:?} found for type {:?}", - declaration, self.items.get(&id).unwrap().kind().expect_type()); + declaration, + self.items.get(&id).unwrap().kind().expect_type()); return; } @@ -183,7 +194,9 @@ impl<'ctx> BindgenContext<'ctx> { } else if let Some(usr) = declaration.usr() { TypeKey::USR(usr) } else { - error!("Valid declaration with no USR: {:?}, {:?}", declaration, location); + error!("Valid declaration with no USR: {:?}, {:?}", + declaration, + location); return; }; @@ -209,18 +222,15 @@ impl<'ctx> BindgenContext<'ctx> { use syntax::parse::token; let ident = self.rust_ident_raw(&name); let token = token::Ident(ident); - if token.is_any_keyword() || - name.contains("@") || - name.contains("?") || - name.contains("$") || - "bool" == name - { + if token.is_any_keyword() || name.contains("@") || + name.contains("?") || name.contains("$") || + "bool" == name { let mut s = name.to_owned(); s = s.replace("@", "_"); s = s.replace("?", "_"); s = s.replace("$", "_"); s.push_str("_"); - return Cow::Owned(s) + return Cow::Owned(s); } Cow::Borrowed(name) } @@ -248,7 +258,9 @@ impl<'ctx> BindgenContext<'ctx> { } /// Gather all the unresolved type references. - fn collect_typerefs(&mut self) -> Vec<(ItemId, clang::Type, Option, Option)> { + fn collect_typerefs + (&mut self) + -> Vec<(ItemId, clang::Type, Option, Option)> { debug_assert!(!self.collected_typerefs); self.collected_typerefs = true; let mut typerefs = vec![]; @@ -263,7 +275,7 @@ impl<'ctx> BindgenContext<'ctx> { TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) => { typerefs.push((*id, ty.clone(), loc, parent_id)); } - _ => {}, + _ => {} }; } typerefs @@ -276,7 +288,7 @@ impl<'ctx> BindgenContext<'ctx> { for (id, ty, loc, parent_id) in typerefs { let _resolved = { let resolved = Item::from_ty(&ty, loc, parent_id, self) - .expect("What happened?"); + .expect("What happened?"); let mut item = self.items.get_mut(&id).unwrap(); *item.kind_mut().as_type_mut().unwrap().kind_mut() = @@ -321,7 +333,8 @@ impl<'ctx> BindgenContext<'ctx> { continue; } - if let Some(replacement) = self.replacements.get(&item.canonical_name(self)) { + if let Some(replacement) = self.replacements + .get(&item.canonical_name(self)) { if replacement != id { // We set this just after parsing the annotation. It's // very unlikely, but this can happen. @@ -342,7 +355,7 @@ impl<'ctx> BindgenContext<'ctx> { /// Enter the code generation phase, invoke the given callback `cb`, and /// leave the code generation phase. pub fn gen(&mut self, cb: F) -> Out - where F: FnOnce(&Self) -> Out + where F: FnOnce(&Self) -> Out, { use syntax::ext::expand::ExpansionConfig; use syntax::codemap::{ExpnInfo, MacroBang, NameAndSpan}; @@ -361,8 +374,8 @@ impl<'ctx> BindgenContext<'ctx> { callee: NameAndSpan { format: MacroBang(parse::token::intern("")), allow_internal_unstable: false, - span: None - } + span: None, + }, }); // FIXME: This is evil, we should move code generation to use a wrapper @@ -471,7 +484,8 @@ impl<'ctx> BindgenContext<'ctx> { wrapping: ItemId, parent_id: ItemId, ty: &clang::Type, - location: clang::Cursor) -> ItemId { + location: clang::Cursor) + -> ItemId { use clangll::*; let mut args = vec![]; let mut found_invalid_template_ref = false; @@ -481,8 +495,10 @@ impl<'ctx> BindgenContext<'ctx> { found_invalid_template_ref = true; } if c.kind() == CXCursor_TypeRef { - let new_ty = - Item::from_ty_or_ref(c.cur_type(), Some(*c), Some(with_id), self); + let new_ty = Item::from_ty_or_ref(c.cur_type(), + Some(*c), + Some(with_id), + self); args.push(new_ty); } CXChildVisit_Continue @@ -520,14 +536,18 @@ impl<'ctx> BindgenContext<'ctx> { // That being said, this is not so common, so just error! and hope // for the best, returning the previous type, who knows. if old_args.len() != args.len() { - error!("Found partial template specialization, expect dragons!"); + error!("Found partial template specialization, \ + expect dragons!"); return wrapping; } let type_kind = TypeKind::TemplateRef(wrapping, args); let name = ty.spelling(); let name = if name.is_empty() { None } else { Some(name) }; - let ty = Type::new(name, ty.fallible_layout().ok(), type_kind, ty.is_const()); + let ty = Type::new(name, + ty.fallible_layout().ok(), + type_kind, + ty.is_const()); Item::new(with_id, None, None, parent_id, ItemKind::Type(ty)) }; @@ -542,32 +562,40 @@ impl<'ctx> BindgenContext<'ctx> { with_id: ItemId, parent_id: Option, ty: &clang::Type, - location: Option) -> Option { - use clangll::{CXCursor_ClassTemplate, CXCursor_ClassTemplatePartialSpecialization}; - debug!("builtin_or_resolved_ty: {:?}, {:?}, {:?}", ty, location, parent_id); + location: Option) + -> Option { + use clangll::{CXCursor_ClassTemplate, + CXCursor_ClassTemplatePartialSpecialization}; + debug!("builtin_or_resolved_ty: {:?}, {:?}, {:?}", + ty, + location, + parent_id); let mut declaration = ty.declaration(); if !declaration.is_valid() { if let Some(location) = location { if location.kind() == CXCursor_ClassTemplate || - location.kind() == CXCursor_ClassTemplatePartialSpecialization { + location.kind() == + CXCursor_ClassTemplatePartialSpecialization { declaration = location; } } } let canonical_declaration = declaration.canonical(); if canonical_declaration.is_valid() { - let id = - self.types.get(&TypeKey::Declaration(canonical_declaration)) - .map(|id| *id) - .or_else(|| { - canonical_declaration.usr().and_then(|usr| { - self.types.get(&TypeKey::USR(usr)) - }) + let id = self.types + .get(&TypeKey::Declaration(canonical_declaration)) + .map(|id| *id) + .or_else(|| { + canonical_declaration.usr() + .and_then(|usr| self.types.get(&TypeKey::USR(usr))) .map(|id| *id) - }); + }); if let Some(id) = id { debug!("Already resolved ty {:?}, {:?}, {:?} {:?}", - id, declaration, ty, location); + id, + declaration, + ty, + location); // If the declaration existed, we *might* be done, but it's not // the case for class templates, where the template arguments @@ -580,13 +608,16 @@ impl<'ctx> BindgenContext<'ctx> { // location for building the new arguments, the template // argument names don't matter in the global context. if (declaration.kind() == CXCursor_ClassTemplate || - declaration.kind() == CXCursor_ClassTemplatePartialSpecialization) && + declaration.kind() == + CXCursor_ClassTemplatePartialSpecialization) && *ty != canonical_declaration.cur_type() && - location.is_some() && parent_id.is_some() { - return Some( - self.build_template_wrapper(with_id, id, - parent_id.unwrap(), ty, - location.unwrap())); + location.is_some() && + parent_id.is_some() { + return Some(self.build_template_wrapper(with_id, + id, + parent_id.unwrap(), + ty, + location.unwrap())); } return Some(self.build_ty_wrapper(with_id, id, parent_id, ty)); @@ -608,21 +639,26 @@ impl<'ctx> BindgenContext<'ctx> { with_id: ItemId, wrapped_id: ItemId, parent_id: Option, - ty: &clang::Type) -> ItemId { + ty: &clang::Type) + -> ItemId { let spelling = ty.spelling(); let is_const = ty.is_const(); let layout = ty.fallible_layout().ok(); let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); let ty = Type::new(Some(spelling), layout, type_kind, is_const); - let item = Item::new(with_id, None, None, - parent_id.unwrap_or(self.current_module), ItemKind::Type(ty)); + let item = Item::new(with_id, + None, + None, + parent_id.unwrap_or(self.current_module), + ItemKind::Type(ty)); self.add_builtin_item(item); with_id } fn build_builtin_ty(&mut self, ty: &clang::Type, - _declaration: Cursor) -> Option { + _declaration: Cursor) + -> Option { use clangll::*; let type_kind = match ty.kind() { CXType_NullPtr => TypeKind::NullPtr, @@ -630,14 +666,11 @@ impl<'ctx> BindgenContext<'ctx> { CXType_Bool => TypeKind::Int(IntKind::Bool), CXType_Int => TypeKind::Int(IntKind::Int), CXType_UInt => TypeKind::Int(IntKind::UInt), - CXType_SChar | - CXType_Char_S => TypeKind::Int(IntKind::Char), - CXType_UChar | - CXType_Char_U => TypeKind::Int(IntKind::UChar), + CXType_SChar | CXType_Char_S => TypeKind::Int(IntKind::Char), + CXType_UChar | CXType_Char_U => TypeKind::Int(IntKind::UChar), CXType_Short => TypeKind::Int(IntKind::Short), CXType_UShort => TypeKind::Int(IntKind::UShort), - CXType_WChar | - CXType_Char16 => TypeKind::Int(IntKind::U16), + CXType_WChar | CXType_Char16 => TypeKind::Int(IntKind::U16), CXType_Char32 => TypeKind::Int(IntKind::U32), CXType_Long => TypeKind::Int(IntKind::Long), CXType_ULong => TypeKind::Int(IntKind::ULong), @@ -656,7 +689,8 @@ impl<'ctx> BindgenContext<'ctx> { let layout = ty.fallible_layout().ok(); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let id = ItemId::next(); - let item = Item::new(id, None, None, self.root_module, ItemKind::Type(ty)); + let item = + Item::new(id, None, None, self.root_module, ItemKind::Type(ty)); self.add_builtin_item(item); Some(id) } @@ -697,7 +731,7 @@ impl<'ctx> BindgenContext<'ctx> { debug_assert!(self.in_codegen_phase(), "You're not supposed to call this yet"); self.options.hidden_types.contains(name) || - self.is_replaced_type(name, id) + self.is_replaced_type(name, id) } /// Has the item with the given `name` and `id` been replaced by another @@ -733,19 +767,23 @@ impl<'ctx> BindgenContext<'ctx> { }; let module_name = self.translation_unit - .tokens(&cursor).and_then(|tokens| { - if tokens.len() <= 1 { - None - } else { - match &*tokens[1].spelling { - "{" => None, - s => Some(s.to_owned()), + .tokens(&cursor) + .and_then(|tokens| { + if tokens.len() <= 1 { + None + } else { + match &*tokens[1].spelling { + "{" => None, + s => Some(s.to_owned()), + } } - } - }); + }); let module = Module::new(module_name); - let module = Item::new(module_id, None, None, self.current_module, + let module = Item::new(module_id, + None, + None, + self.current_module, ItemKind::Module(module)); self.add_item(module, None, None); @@ -756,7 +794,7 @@ impl<'ctx> BindgenContext<'ctx> { /// Start traversing the module with the given `module_id`, invoke the /// callback `cb`, and then return to traversing the original module. pub fn with_module(&mut self, module_id: ItemId, cb: F) - where F: FnOnce(&mut Self, &mut Vec) + where F: FnOnce(&mut Self, &mut Vec), { debug_assert!(self.resolve_item(module_id).kind().is_module(), "Wat"); @@ -766,9 +804,13 @@ impl<'ctx> BindgenContext<'ctx> { let mut children = vec![]; cb(self, &mut children); - self.items.get_mut(&module_id).unwrap() - .as_module_mut().expect("Not a module?") - .children_mut().extend(children.into_iter()); + self.items + .get_mut(&module_id) + .unwrap() + .as_module_mut() + .expect("Not a module?") + .children_mut() + .extend(children.into_iter()); self.current_module = previous_id; } diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index aff5130bcb..fd7dbb4562 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -1,10 +1,10 @@ //! Intermediate representation for C/C++ enumerations. +use clang; +use parse::{ClangItemParser, ParseError}; +use super::context::BindgenContext; use super::item::{Item, ItemId}; use super::ty::TypeKind; -use super::context::BindgenContext; -use parse::{ClangItemParser, ParseError}; -use clang; /// A C/C++ enumeration. #[derive(Debug)] @@ -41,14 +41,16 @@ impl Enum { /// Construct an enumeration from the given Clang type. pub fn from_ty(ty: &clang::Type, - ctx: &mut BindgenContext) -> Result { + ctx: &mut BindgenContext) + -> Result { use clangll::*; if ty.kind() != CXType_Enum { return Err(ParseError::Continue); } let declaration = ty.declaration().canonical(); - let repr = Item::from_ty(&declaration.enum_type(), None, None, ctx).ok(); + let repr = Item::from_ty(&declaration.enum_type(), None, None, ctx) + .ok(); let mut variants = vec![]; let is_signed = match repr { @@ -56,10 +58,14 @@ impl Enum { let repr_type = ctx.resolve_type(repr); match *repr_type.canonical_type(ctx).kind() { TypeKind::Int(ref int_kind) => int_kind.is_signed(), - ref other => panic!("Since when enums can be non-integers? {:?}", other), + ref other => { + panic!("Since when enums can be non-integers? {:?}", + other) + } } } - // Assume signedness since the default type by the C standard is an + // Assume signedness since the default type by the C + // standard is an // int. None => true, }; @@ -107,7 +113,10 @@ pub enum EnumVariantValue { impl EnumVariant { /// Construct a new enumeration variant from the given parts. - pub fn new(name: String, comment: Option, val: EnumVariantValue) -> Self { + pub fn new(name: String, + comment: Option, + val: EnumVariantValue) + -> Self { EnumVariant { name: name, comment: comment, diff --git a/src/ir/function.rs b/src/ir/function.rs index e9fd4a2505..c2e6ffd076 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -1,13 +1,13 @@ //! Intermediate representation for C/C++ functions and methods. +use clang; +use clangll::Enum_CXCallingConv; +use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use super::context::BindgenContext; use super::item::{Item, ItemId}; use super::ty::TypeKind; use super::type_collector::{ItemSet, TypeCollector}; use syntax::abi; -use clang; -use clangll::Enum_CXCallingConv; -use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; /// A function declaration, with a signature, arguments, and argument names. /// @@ -33,7 +33,8 @@ impl Function { pub fn new(name: String, mangled_name: Option, sig: ItemId, - comment: Option) -> Self { + comment: Option) + -> Self { Function { name: name, mangled_name: mangled_name, @@ -115,7 +116,8 @@ impl FunctionSig { pub fn new(return_type: ItemId, arguments: Vec<(Option, ItemId)>, is_variadic: bool, - abi: abi::Abi) -> Self { + abi: abi::Abi) + -> Self { FunctionSig { return_type: return_type, argument_types: arguments, @@ -127,7 +129,8 @@ impl FunctionSig { /// Construct a new function signature from the given Clang type. pub fn from_ty(ty: &clang::Type, cursor: &clang::Cursor, - ctx: &mut BindgenContext) -> Result { + ctx: &mut BindgenContext) + -> Result { use clangll::*; debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor); @@ -147,14 +150,18 @@ impl FunctionSig { CXCursor_CXXMethod => { // For CXCursor_FunctionDecl, cursor.args() is the reliable way // to get parameter names and types. - cursor.args().iter().map(|arg| { - let arg_ty = arg.cur_type(); - let name = arg.spelling(); - let name = if name.is_empty() { None } else { Some(name) }; - let ty = Item::from_ty(&arg_ty, Some(*arg), None, ctx) - .expect("Argument?"); - (name, ty) - }).collect() + cursor.args() + .iter() + .map(|arg| { + let arg_ty = arg.cur_type(); + let name = arg.spelling(); + let name = + if name.is_empty() { None } else { Some(name) }; + let ty = Item::from_ty(&arg_ty, Some(*arg), None, ctx) + .expect("Argument?"); + (name, ty) + }) + .collect() } _ => { // For non-CXCursor_FunctionDecl, visiting the cursor's children @@ -162,10 +169,12 @@ impl FunctionSig { let mut args = vec![]; cursor.visit(|c, _| { if c.kind() == CXCursor_ParmDecl { - let ty = Item::from_ty(&c.cur_type(), Some(*c), None, ctx) - .expect("ParmDecl?"); + let ty = + Item::from_ty(&c.cur_type(), Some(*c), None, ctx) + .expect("ParmDecl?"); let name = c.spelling(); - let name = if name.is_empty() { None } else { Some(name) }; + let name = + if name.is_empty() { None } else { Some(name) }; args.push((name, ty)); } CXChildVisit_Continue @@ -180,12 +189,14 @@ impl FunctionSig { let is_static = cursor.method_is_static(); if !is_static && !is_virtual { let class = Item::parse(cursor.semantic_parent(), None, ctx) - .expect("Expected to parse the class"); - let ptr = Item::builtin_type(TypeKind::Pointer(class), is_const, ctx); + .expect("Expected to parse the class"); + let ptr = + Item::builtin_type(TypeKind::Pointer(class), is_const, ctx); args.insert(0, (Some("this".into()), ptr)); } else if is_virtual { let void = Item::builtin_type(TypeKind::Void, false, ctx); - let ptr = Item::builtin_type(TypeKind::Pointer(void), false, ctx); + let ptr = + Item::builtin_type(TypeKind::Pointer(void), false, ctx); args.insert(0, (Some("this".into()), ptr)); } } @@ -223,18 +234,22 @@ impl FunctionSig { impl ClangSubItemParser for Function { fn parse(cursor: clang::Cursor, - context: &mut BindgenContext) -> Result, ParseError> { + context: &mut BindgenContext) + -> Result, ParseError> { use clangll::*; match cursor.kind() { CXCursor_FunctionDecl | - CXCursor_CXXMethod => {}, + CXCursor_CXXMethod => {} _ => return Err(ParseError::Continue), }; debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type()); // Grab the signature using Item::from_ty. - let sig = try!(Item::from_ty(&cursor.cur_type(), Some(cursor), None, context)); + let sig = try!(Item::from_ty(&cursor.cur_type(), + Some(cursor), + None, + context)); let name = cursor.spelling(); assert!(!name.is_empty(), "Empty function name?"); diff --git a/src/ir/int.rs b/src/ir/int.rs index ed26acc4cb..a18e4c588a 100644 --- a/src/ir/int.rs +++ b/src/ir/int.rs @@ -46,9 +46,8 @@ pub enum IntKind { I128, /// A `uint128_t`. - U128, - - // Though now we're at it we could add equivalents for the rust types... + U128, /* Though now we're at it we could add equivalents for the rust + * types... */ } impl IntKind { @@ -56,11 +55,10 @@ impl IntKind { pub fn is_signed(&self) -> bool { use self::IntKind::*; match *self { - Bool | UChar | UShort | - UInt | ULong | ULongLong | U16 | U32 | U128 => false, + Bool | UChar | UShort | UInt | ULong | ULongLong | U16 | U32 | + U128 => false, - Char | Short | Int | - Long | LongLong | I128 => true, + Char | Short | Int | Long | LongLong | I128 => true, } } } diff --git a/src/ir/item.rs b/src/ir/item.rs index a6d15cd7c6..4e893e357b 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -1,17 +1,17 @@ //! Bindgen's core intermediate representation type. +use clang; +use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use regex::Regex; +use std::cell::{Cell, RefCell}; +use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; +use super::annotations::Annotations; use super::context::BindgenContext; +use super::function::Function; use super::item_kind::ItemKind; +use super::module::Module; use super::ty::{Type, TypeKind}; use super::type_collector::{ItemSet, TypeCollector}; -use super::function::Function; -use super::module::Module; -use super::annotations::Annotations; -use std::cell::{Cell, RefCell}; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; -use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; -use clang; /// A trait to get the canonical name from an item. /// @@ -80,10 +80,10 @@ impl TypeCollector for ItemId { type Extra = (); fn collect_types(&self, - context: &BindgenContext, + ctx: &BindgenContext, types: &mut ItemSet, extra: &()) { - context.resolve_item(*self).collect_types(context, types, extra); + ctx.resolve_item(*self).collect_types(ctx, types, extra); } } @@ -91,21 +91,21 @@ impl TypeCollector for Item { type Extra = (); fn collect_types(&self, - context: &BindgenContext, + ctx: &BindgenContext, types: &mut ItemSet, _extra: &()) { - if self.is_hidden(context) || types.contains(&self.id()) { + if self.is_hidden(ctx) || types.contains(&self.id()) { return; } match *self.kind() { ItemKind::Type(ref ty) => { types.insert(self.id()); - if !self.is_opaque(context) { - ty.collect_types(context, types, self); + if !self.is_opaque(ctx) { + ty.collect_types(ctx, types, self); } } - _ => {}, // FIXME. + _ => {} // FIXME. } } } @@ -171,7 +171,8 @@ impl Item { comment: Option, annotations: Option, parent_id: ItemId, - kind: ItemKind) -> Self { + kind: ItemKind) + -> Self { debug_assert!(id != parent_id || kind.is_module()); Item { id: id, @@ -248,8 +249,7 @@ impl Item { pub fn is_toplevel(&self, ctx: &BindgenContext) -> bool { // FIXME: Workaround for some types falling behind when parsing weird // stl classes, for example. - if ctx.options().enable_cxx_namespaces && - self.kind().is_module() && + if ctx.options().enable_cxx_namespaces && self.kind().is_module() && self.id() != ctx.root_module() { return false; } @@ -263,7 +263,8 @@ impl Item { if parent_item.id() == ctx.root_module() { return true; - } else if ctx.options().enable_cxx_namespaces || !parent_item.kind().is_module() { + } else if ctx.options().enable_cxx_namespaces || + !parent_item.kind().is_module() { return false; } @@ -328,16 +329,19 @@ impl Item { /// Normally we could do this check just in the `Type` kind, but we also /// need to check the `applicable_template_args` more generally, since we /// could need a type transitively from our parent, see the test added in - /// + /// commit 2a3f93074dd2898669dbbce6e97e5cc4405d7cb1. /// /// It's kind of unfortunate (in the sense that it's a sort of complex /// process), but I think it should get all the cases. - fn signature_contains_named_type(&self, ctx: &BindgenContext, ty: &Type) -> bool { + fn signature_contains_named_type(&self, + ctx: &BindgenContext, + ty: &Type) + -> bool { debug_assert!(ty.is_named()); self.expect_type().signature_contains_named_type(ctx, ty) || - self.applicable_template_args(ctx).iter().any(|template| { - ctx.resolve_type(*template).signature_contains_named_type(ctx, ty) - }) + self.applicable_template_args(ctx).iter().any(|template| { + ctx.resolve_type(*template).signature_contains_named_type(ctx, ty) + }) } /// Returns the template arguments that apply to a struct. This is a concept @@ -373,7 +377,9 @@ impl Item { /// the template parameter type `T`, and that's exactly what this method /// represents. The unused template parameters get stripped in the /// `signature_contains_named_type` check. - pub fn applicable_template_args(&self, ctx: &BindgenContext) -> Vec { + pub fn applicable_template_args(&self, + ctx: &BindgenContext) + -> Vec { let ty = match *self.kind() { ItemKind::Type(ref ty) => ty, _ => return vec![], @@ -381,12 +387,14 @@ impl Item { fn parent_contains(ctx: &BindgenContext, parent_template_args: &[ItemId], - item: ItemId) -> bool { + item: ItemId) + -> bool { let item_ty = ctx.resolve_type(item); parent_template_args.iter().any(|parent_item| { let parent_ty = ctx.resolve_type(*parent_item); match (parent_ty.kind(), item_ty.kind()) { - (&TypeKind::Named(ref n, _), &TypeKind::Named(ref i, _)) => n == i, + (&TypeKind::Named(ref n, _), + &TypeKind::Named(ref i, _)) => n == i, _ => false, } }) @@ -402,21 +410,23 @@ impl Item { } TypeKind::Alias(_, inner) => { let parent_args = ctx.resolve_item(self.parent_id()) - .applicable_template_args(ctx); + .applicable_template_args(ctx); let inner = ctx.resolve_item(inner); // Avoid unused type parameters, sigh. - parent_args.iter().cloned().filter(|arg| { - let arg = ctx.resolve_type(*arg); - arg.is_named() && inner.signature_contains_named_type(ctx, arg) - }).collect() + parent_args.iter() + .cloned() + .filter(|arg| { + let arg = ctx.resolve_type(*arg); + arg.is_named() && + inner.signature_contains_named_type(ctx, arg) + }) + .collect() } // XXX Is this completely correct? Partial template specialization // is hard anyways, sigh... TypeKind::TemplateAlias(_, ref args) | - TypeKind::TemplateRef(_, ref args) => { - args.clone() - } + TypeKind::TemplateRef(_, ref args) => args.clone(), // In a template specialization we've got all we want. TypeKind::Comp(ref ci) if ci.is_template_specialization() => { ci.template_args().iter().cloned().collect() @@ -424,7 +434,7 @@ impl Item { TypeKind::Comp(ref ci) => { let mut parent_template_args = ctx.resolve_item(self.parent_id()) - .applicable_template_args(ctx); + .applicable_template_args(ctx); for ty in ci.template_args() { if !parent_contains(ctx, &parent_template_args, *ty) { @@ -457,7 +467,7 @@ impl Item { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); self.annotations.hide() || - ctx.hidden_by_name(&self.real_canonical_name(ctx, false, true), self.id) + ctx.hidden_by_name(&self.real_canonical_name(ctx, false, true), self.id) } /// Is this item opaque? @@ -465,7 +475,7 @@ impl Item { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); self.annotations.opaque() || - ctx.opaque_by_name(&self.real_canonical_name(ctx, false, true)) + ctx.opaque_by_name(&self.real_canonical_name(ctx, false, true)) } /// Get the canonical name without taking into account the replaces @@ -482,13 +492,17 @@ impl Item { fn real_canonical_name(&self, ctx: &BindgenContext, count_namespaces: bool, - for_name_checking: bool) -> String { + for_name_checking: bool) + -> String { let base_name = match *self.kind() { ItemKind::Type(ref ty) => { match *ty.kind() { - // If we're a template specialization, our name is our parent's - TypeKind::Comp(ref ci) if ci.is_template_specialization() => { - return ci.specialized_template().unwrap().canonical_name(ctx); + // If we're a template specialization, our name is our + // parent's. + TypeKind::Comp(ref ci) + if ci.is_template_specialization() => { + return ci.specialized_template().unwrap() + .canonical_name(ctx); }, // Same as above TypeKind::ResolvedTypeRef(inner) | @@ -512,7 +526,10 @@ impl Item { // would be needed. TypeKind::TemplateAlias(inner, _) => { if for_name_checking { - return ctx.resolve_item(inner).real_canonical_name(ctx, count_namespaces, false); + return ctx.resolve_item(inner) + .real_canonical_name(ctx, + count_namespaces, + false); } Some("") } @@ -538,7 +555,7 @@ impl Item { break; } let fun = ctx.resolve_item(method.signature()) - .expect_function(); + .expect_function(); if fun.name() == base { count += 1; } @@ -552,9 +569,7 @@ impl Item { } Some(base) } - ItemKind::Var(ref var) => { - Some(var.name().to_owned()) - } + ItemKind::Var(ref var) => Some(var.name().to_owned()), ItemKind::Module(ref module) => { module.name().map(ToOwned::to_owned) } @@ -595,10 +610,14 @@ impl Item { fn make_exposed_name(&self, parent_name: Option, base_name: Option, - ctx: &BindgenContext) -> String { + ctx: &BindgenContext) + -> String { lazy_static! { - static ref RE_ENDS_WITH_BINDGEN_TY: Regex = Regex::new(r"_bindgen_ty(_\d+)+$").unwrap(); - static ref RE_ENDS_WITH_BINDGEN_MOD: Regex = Regex::new(r"_bindgen_mod(_\d+)+$").unwrap(); + static ref RE_ENDS_WITH_BINDGEN_TY: Regex = + Regex::new(r"_bindgen_ty(_\d+)+$").unwrap(); + + static ref RE_ENDS_WITH_BINDGEN_MOD: Regex = + Regex::new(r"_bindgen_mod(_\d+)+$").unwrap(); } let (re, kind) = match *self.kind() { @@ -606,18 +625,24 @@ impl Item { _ => (&*RE_ENDS_WITH_BINDGEN_TY, "ty"), }; - let parent_name = parent_name.and_then(|n| if n.is_empty() { None } else { Some(n) }); + let parent_name = + parent_name.and_then(|n| if n.is_empty() { None } else { Some(n) }); match (parent_name, base_name) { (Some(parent), Some(base)) => format!("{}_{}", parent, base), (Some(parent), None) => { if re.is_match(parent.as_str()) { format!("{}_{}", parent, self.exposed_id(ctx)) } else { - format!("{}__bindgen_{}_{}", parent, kind, self.exposed_id(ctx)) + format!("{}__bindgen_{}_{}", + parent, + kind, + self.exposed_id(ctx)) } } (None, Some(base)) => base, - (None, None) => format!("_bindgen_{}_{}", kind, self.exposed_id(ctx)), + (None, None) => { + format!("_bindgen_{}_{}", kind, self.exposed_id(ctx)) + } } } @@ -645,13 +670,16 @@ impl Item { } impl ClangItemParser for Item { - fn builtin_type(kind: TypeKind, is_const: bool, ctx: &mut BindgenContext) -> ItemId { + fn builtin_type(kind: TypeKind, + is_const: bool, + ctx: &mut BindgenContext) + -> ItemId { // Feel free to add more here, I'm just lazy. match kind { TypeKind::Void | TypeKind::Int(..) | TypeKind::Pointer(..) | - TypeKind::Float(..) => {}, + TypeKind::Float(..) => {} _ => panic!("Unsupported builtin type"), } @@ -659,14 +687,16 @@ impl ClangItemParser for Item { let id = ItemId::next(); let module = ctx.root_module(); ctx.add_item(Item::new(id, None, None, module, ItemKind::Type(ty)), - None, None); + None, + None); id } fn parse(cursor: clang::Cursor, parent_id: Option, - context: &mut BindgenContext) -> Result { + ctx: &mut BindgenContext) + -> Result { use ir::function::Function; use ir::module::Module; use ir::var::Var; @@ -679,15 +709,18 @@ impl ClangItemParser for Item { let comment = cursor.raw_comment(); let annotations = Annotations::new(&cursor); - let current_module = context.current_module(); + let current_module = ctx.current_module(); + let relevant_parent_id = parent_id.unwrap_or(current_module); + macro_rules! try_parse { ($what:ident) => { - match $what::parse(cursor, context) { + match $what::parse(cursor, ctx) { Ok(ParseResult::New(item, declaration)) => { let id = ItemId::next(); - context.add_item(Item::new(id, comment, annotations, - parent_id.unwrap_or(current_module), - ItemKind::$what(item)), + + ctx.add_item(Item::new(id, comment, annotations, + relevant_parent_id, + ItemKind::$what(item)), declaration, Some(cursor)); return Ok(id); @@ -723,11 +756,12 @@ impl ClangItemParser for Item { cursor }; match Self::from_ty(&applicable_cursor.cur_type(), - Some(applicable_cursor), parent_id, context) - { + Some(applicable_cursor), + parent_id, + ctx) { Ok(ty) => return Ok(ty), Err(ParseError::Recurse) => return Err(ParseError::Recurse), - Err(ParseError::Continue) => {}, + Err(ParseError::Continue) => {} } } @@ -741,11 +775,13 @@ impl ClangItemParser for Item { CXCursor_MacroDefinition | CXCursor_InclusionDirective => { debug!("Unhandled cursor kind {:?}: {:?}", - cursor.kind(), cursor); - }, - _ =>{ + cursor.kind(), + cursor); + } + _ => { error!("Unhandled cursor kind {:?}: {:?}", - cursor.kind(), cursor); + cursor.kind(), + cursor); } } @@ -756,8 +792,13 @@ impl ClangItemParser for Item { fn from_ty_or_ref(ty: clang::Type, location: Option, parent_id: Option, - context: &mut BindgenContext) -> ItemId { - Self::from_ty_or_ref_with_id(ItemId::next(), ty, location, parent_id, context) + ctx: &mut BindgenContext) + -> ItemId { + Self::from_ty_or_ref_with_id(ItemId::next(), + ty, + location, + parent_id, + ctx) } /// Parse a C++ type. If we find a reference to a type that has not been @@ -774,18 +815,27 @@ impl ClangItemParser for Item { ty: clang::Type, location: Option, parent_id: Option, - context: &mut BindgenContext) -> ItemId { - debug!("from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}", potential_id, ty, location, parent_id); - - if context.collected_typerefs() { + ctx: &mut BindgenContext) + -> ItemId { + debug!("from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}", + potential_id, + ty, + location, + parent_id); + + if ctx.collected_typerefs() { debug!("refs already collected, resolving directly"); - return Self::from_ty_with_id(potential_id, &ty, location, parent_id, context) - .expect("Unable to resolve type"); + return Self::from_ty_with_id(potential_id, + &ty, + location, + parent_id, + ctx) + .expect("Unable to resolve type"); } - if let Some(ty) = context.builtin_or_resolved_ty(potential_id, - parent_id, &ty, - location) { + if let Some(ty) = ctx.builtin_or_resolved_ty(potential_id, + parent_id, &ty, + location) { debug!("{:?} already resolved: {:?}", ty, location); return ty; } @@ -794,12 +844,17 @@ impl ClangItemParser for Item { let is_const = ty.is_const(); let kind = TypeKind::UnresolvedTypeRef(ty, location, parent_id); - let current_module = context.current_module(); - context.add_item(Item::new(potential_id, None, None, - parent_id.unwrap_or(current_module), - ItemKind::Type(Type::new(None, None, kind, is_const))), - Some(clang::Cursor::null()), - None); + let current_module = ctx.current_module(); + ctx.add_item(Item::new(potential_id, + None, + None, + parent_id.unwrap_or(current_module), + ItemKind::Type(Type::new(None, + None, + kind, + is_const))), + Some(clang::Cursor::null()), + None); potential_id } @@ -807,8 +862,9 @@ impl ClangItemParser for Item { fn from_ty(ty: &clang::Type, location: Option, parent_id: Option, - context: &mut BindgenContext) -> Result { - Self::from_ty_with_id(ItemId::next(), ty, location, parent_id, context) + ctx: &mut BindgenContext) + -> Result { + Self::from_ty_with_id(ItemId::next(), ty, location, parent_id, ctx) } /// This is one of the trickiest methods you'll find (probably along with @@ -823,7 +879,8 @@ impl ClangItemParser for Item { ty: &clang::Type, location: Option, parent_id: Option, - context: &mut BindgenContext) -> Result { + ctx: &mut BindgenContext) + -> Result { use clangll::*; let decl = { @@ -836,19 +893,19 @@ impl ClangItemParser for Item { } }; - let comment = - decl.raw_comment() - .or_else(|| location.as_ref().and_then(|l| l.raw_comment())); - let annotations = - Annotations::new(&decl) - .or_else(|| location.as_ref().and_then(|l| Annotations::new(l))); + let comment = decl.raw_comment() + .or_else(|| location.as_ref().and_then(|l| l.raw_comment())); + let annotations = Annotations::new(&decl) + .or_else(|| location.as_ref().and_then(|l| Annotations::new(l))); - if let Some(ref replaced) = annotations.as_ref().and_then(|a| a.use_instead_of()) { - context.replace(replaced, id); + if let Some(ref annotations) = annotations { + if let Some(ref replaced) = annotations.use_instead_of() { + ctx.replace(replaced, id); + } } - if let Some(ty) = context.builtin_or_resolved_ty(id, parent_id, - ty, location) { + if let Some(ty) = + ctx.builtin_or_resolved_ty(id, parent_id, ty, location) { return Ok(ty); } @@ -856,7 +913,9 @@ impl ClangItemParser for Item { let mut valid_decl = decl.kind() != CXCursor_NoDeclFound; let declaration_to_look_for = if valid_decl { decl.canonical() - } else if location.is_some() && location.unwrap().kind() == CXCursor_ClassTemplate { + } else if location.is_some() && + location.unwrap().kind() == + CXCursor_ClassTemplate { valid_decl = true; location.unwrap() } else { @@ -864,26 +923,31 @@ impl ClangItemParser for Item { }; if valid_decl { - if let Some(&(_, item_id)) = context.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); } } - let current_module = context.current_module(); + let current_module = ctx.current_module(); if valid_decl { - context.currently_parsed_types.push((declaration_to_look_for, id)); + ctx.currently_parsed_types.push((declaration_to_look_for, id)); } - let result = Type::from_clang_ty(id, ty, location, parent_id, context); + let result = Type::from_clang_ty(id, ty, location, parent_id, ctx); + let relevant_parent_id = parent_id.unwrap_or(current_module); let ret = match result { Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty), Ok(ParseResult::New(item, declaration)) => { - context.add_item(Item::new(id, comment, annotations, - parent_id.unwrap_or(current_module), - ItemKind::Type(item)), - declaration, - location); + ctx.add_item(Item::new(id, + comment, + annotations, + relevant_parent_id, + ItemKind::Type(item)), + declaration, + location); Ok(id) } Err(ParseError::Continue) => Err(ParseError::Continue), @@ -897,13 +961,18 @@ impl ClangItemParser for Item { // declaration_to_look_for suspiciously shares a lot of // logic with ir::context, so we should refactor that. if valid_decl { - let (popped_decl, _) = context.currently_parsed_types.pop().unwrap(); + let (popped_decl, _) = + ctx.currently_parsed_types.pop().unwrap(); assert_eq!(popped_decl, declaration_to_look_for); } location.visit(|cur, _other| { use clangll::*; - result = Item::from_ty_with_id(id, ty, Some(*cur), parent_id, context); + result = Item::from_ty_with_id(id, + ty, + Some(*cur), + parent_id, + ctx); match result { Ok(..) => CXChildVisit_Break, Err(ParseError::Recurse) => CXChildVisit_Recurse, @@ -912,7 +981,8 @@ impl ClangItemParser for Item { }); if valid_decl { - context.currently_parsed_types.push((declaration_to_look_for, id)); + ctx.currently_parsed_types + .push((declaration_to_look_for, id)); } } // If we have recursed into the AST all we know, and we still @@ -925,10 +995,11 @@ impl ClangItemParser for Item { // It's harmless, but if we restrict that, then // tests/headers/nsStyleAutoArray.hpp crashes. if let Err(ParseError::Recurse) = result { - Ok(Self::named_type_with_id(id, ty.spelling(), + Ok(Self::named_type_with_id(id, + ty.spelling(), None, - parent_id.unwrap_or(context.current_module()), - context)) + relevant_parent_id, + ctx)) } else { result } @@ -936,7 +1007,7 @@ impl ClangItemParser for Item { }; if valid_decl { - let (popped_decl, _) = context.currently_parsed_types.pop().unwrap(); + let (popped_decl, _) = ctx.currently_parsed_types.pop().unwrap(); assert_eq!(popped_decl, declaration_to_look_for); } @@ -954,17 +1025,21 @@ impl ClangItemParser for Item { name: S, default: Option, parent_id: ItemId, - context: &mut BindgenContext) -> ItemId - where S: Into + ctx: &mut BindgenContext) + -> ItemId + where S: Into, { // see tests/headers/const_tparam.hpp // and tests/headers/variadic_tname.hpp let name = name.into().replace("const ", "").replace(".", ""); - context.add_item(Item::new(id, None, None, parent_id, - ItemKind::Type(Type::named(name, default))), - None, - None); + ctx.add_item(Item::new(id, + None, + None, + parent_id, + ItemKind::Type(Type::named(name, default))), + None, + None); id } @@ -972,10 +1047,11 @@ impl ClangItemParser for Item { fn named_type(name: S, default: Option, parent_id: ItemId, - context: &mut BindgenContext) -> ItemId - where S: Into + ctx: &mut BindgenContext) + -> ItemId + where S: Into, { - Self::named_type_with_id(ItemId::next(), name, default, parent_id, context) + Self::named_type_with_id(ItemId::next(), name, default, parent_id, ctx) } } @@ -989,7 +1065,8 @@ impl ItemCanonicalName for Item { if self.canonical_name_cache.borrow().is_none() { *self.canonical_name_cache.borrow_mut() = Some(self.real_canonical_name(ctx, - ctx.options().enable_cxx_namespaces, + ctx.options() + .enable_cxx_namespaces, false)); } return self.canonical_name_cache.borrow().as_ref().unwrap().clone(); @@ -1015,8 +1092,10 @@ impl ItemCanonicalPath for Item { if let ItemKind::Type(ref ty) = *self.kind() { match *ty.kind() { TypeKind::Comp(ref ci) if ci.is_template_specialization() => { - return ci.specialized_template().unwrap().canonical_path(ctx); - }, + return ci.specialized_template() + .unwrap() + .canonical_path(ctx); + } TypeKind::ResolvedTypeRef(inner) | TypeKind::TemplateRef(inner, _) => { return inner.canonical_path(ctx); @@ -1029,7 +1108,8 @@ impl ItemCanonicalPath for Item { } let mut parent_path = self.parent_id().canonical_path(&ctx); - if parent_path.last().map_or(false, |parent_name| parent_name.is_empty()) { + if parent_path.last() + .map_or(false, |parent_name| parent_name.is_empty()) { // This only happens (or should only happen) when we're an alias, // and our parent is a templated alias, in which case the last // component of the path will be empty. diff --git a/src/ir/module.rs b/src/ir/module.rs index 591a4e3af8..c582d3eb8a 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -1,10 +1,10 @@ //! Intermediate representation for modules (AKA C++ namespaces). -use super::context::BindgenContext; -use super::item::ItemId; use clang; use parse::{ClangSubItemParser, ParseError, ParseResult}; use parse_one; +use super::context::BindgenContext; +use super::item::ItemId; /// A module, as in, a C++ namespace. #[derive(Clone, Debug)] @@ -41,18 +41,22 @@ impl Module { } impl ClangSubItemParser for Module { - fn parse(cursor: clang::Cursor, ctx: &mut BindgenContext) -> Result, ParseError> { + fn parse(cursor: clang::Cursor, + ctx: &mut BindgenContext) + -> Result, ParseError> { use clangll::*; match cursor.kind() { CXCursor_Namespace => { let module_id = ctx.module(cursor); ctx.with_module(module_id, |ctx, children| { - cursor.visit(|cursor, _| parse_one(ctx, *cursor, Some(module_id), children)) + cursor.visit(|cursor, _| { + parse_one(ctx, *cursor, Some(module_id), children) + }) }); Ok(ParseResult::AlreadyResolved(module_id)) } - _ => Err(ParseError::Continue) + _ => Err(ParseError::Continue), } } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index a914ce14ff..4d26cdff49 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -1,15 +1,15 @@ //! Everything related to types in our intermediate representation. +use clang::{self, Cursor}; +use parse::{ClangItemParser, ParseError, ParseResult}; use super::comp::CompInfo; +use super::context::BindgenContext; use super::enum_ty::Enum; use super::function::FunctionSig; -use super::item::{Item, ItemId}; use super::int::IntKind; +use super::item::{Item, ItemId}; use super::layout::Layout; -use super::context::BindgenContext; use super::type_collector::{ItemSet, TypeCollector}; -use parse::{ClangItemParser, ParseResult, ParseError}; -use clang::{self, Cursor}; /// The base representation of a type in bindgen. /// @@ -49,7 +49,8 @@ impl Type { pub fn new(name: Option, layout: Option, kind: TypeKind, - is_const: bool) -> Self { + is_const: bool) + -> Self { Type { name: name, layout: layout, @@ -141,15 +142,17 @@ impl Type { self.layout.or_else(|| { match self.kind { - TypeKind::Comp(ref ci) - => ci.layout(ctx), + TypeKind::Comp(ref ci) => ci.layout(ctx), // FIXME(emilio): This is a hack for anonymous union templates. // Use the actual pointer size! TypeKind::Pointer(..) | - TypeKind::BlockPointer - => Some(Layout::new(mem::size_of::<*mut ()>(), mem::align_of::<*mut ()>())), - TypeKind::ResolvedTypeRef(inner) - => ctx.resolve_type(inner).layout(ctx), + TypeKind::BlockPointer => { + Some(Layout::new(mem::size_of::<*mut ()>(), + mem::align_of::<*mut ()>())) + } + TypeKind::ResolvedTypeRef(inner) => { + ctx.resolve_type(inner).layout(ctx) + } _ => None, } }) @@ -168,9 +171,7 @@ impl Type { } TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(_, t) => { - ctx.resolve_type(t).can_derive_debug(ctx) - } + TypeKind::Alias(_, t) => ctx.resolve_type(t).can_derive_debug(ctx), TypeKind::Comp(ref info) => { info.can_derive_debug(ctx, self.layout(ctx)) } @@ -200,14 +201,17 @@ impl Type { /// is an error. /// /// That's the whole point of the existence of `can_derive_copy_in_array`. - pub fn can_derive_copy_in_array(&self, ctx: &BindgenContext, item: &Item) -> bool { + pub fn can_derive_copy_in_array(&self, + ctx: &BindgenContext, + item: &Item) + -> bool { match self.kind { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(_, t) | TypeKind::Array(t, _) => { ctx.resolve_item(t) - .can_derive_copy_in_array(ctx) + .can_derive_copy_in_array(ctx) } TypeKind::Named(..) => false, _ => self.can_derive_copy(ctx, item), @@ -225,12 +229,8 @@ impl Type { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::TemplateRef(t, _) | - TypeKind::Alias(_, t) => { - ctx.resolve_item(t).can_derive_copy(ctx) - } - TypeKind::Comp(ref info) => { - info.can_derive_copy(ctx, item) - } + TypeKind::Alias(_, t) => ctx.resolve_item(t).can_derive_copy(ctx), + TypeKind::Comp(ref info) => info.can_derive_copy(ctx, item), _ => true, } } @@ -242,12 +242,8 @@ impl Type { TypeKind::TemplateRef(t, _) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(_, t) | - TypeKind::ResolvedTypeRef(t) => { - ctx.resolve_type(t).has_vtable(ctx) - } - TypeKind::Comp(ref info) => { - info.has_vtable(ctx) - } + TypeKind::ResolvedTypeRef(t) => ctx.resolve_type(t).has_vtable(ctx), + TypeKind::Comp(ref info) => info.has_vtable(ctx), _ => false, } @@ -262,9 +258,7 @@ impl Type { TypeKind::ResolvedTypeRef(t) => { ctx.resolve_type(t).has_destructor(ctx) } - TypeKind::Comp(ref info) => { - info.has_destructor(ctx) - } + TypeKind::Comp(ref info) => info.has_destructor(ctx), _ => false, } } @@ -272,7 +266,8 @@ impl Type { /// See the comment in `Item::signature_contains_named_type`. pub fn signature_contains_named_type(&self, ctx: &BindgenContext, - ty: &Type) -> bool { + ty: &Type) + -> bool { debug_assert!(ty.is_named()); let name = match *ty.kind() { TypeKind::Named(ref name, _) => name, @@ -280,38 +275,40 @@ impl Type { }; match self.kind { - TypeKind::Named(ref this_name, _) - => this_name == name, + TypeKind::Named(ref this_name, _) => this_name == name, TypeKind::ResolvedTypeRef(t) | TypeKind::Array(t, _) | TypeKind::Pointer(t) | - TypeKind::Alias(_, t) - => ctx.resolve_type(t) - .signature_contains_named_type(ctx, ty), + TypeKind::Alias(_, t) => { + ctx.resolve_type(t) + .signature_contains_named_type(ctx, ty) + } TypeKind::Function(ref sig) => { sig.argument_types().iter().any(|&(_, arg)| { ctx.resolve_type(arg) - .signature_contains_named_type(ctx, ty) + .signature_contains_named_type(ctx, ty) }) || ctx.resolve_type(sig.return_type()) - .signature_contains_named_type(ctx, ty) - }, + .signature_contains_named_type(ctx, ty) + } TypeKind::TemplateAlias(_, ref template_args) | TypeKind::TemplateRef(_, ref template_args) => { template_args.iter().any(|arg| { ctx.resolve_type(*arg) - .signature_contains_named_type(ctx, ty) + .signature_contains_named_type(ctx, ty) }) } - TypeKind::Comp(ref ci) - => ci.signature_contains_named_type(ctx, ty), - _ => false, + TypeKind::Comp(ref ci) => ci.signature_contains_named_type(ctx, ty), + _ => false, } } /// See safe_canonical_type. - pub fn canonical_type<'tr>(&'tr self, ctx: &'tr BindgenContext) -> &'tr Type { - self.safe_canonical_type(ctx).expect("Should have been resolved after parsing!") + pub fn canonical_type<'tr>(&'tr self, + ctx: &'tr BindgenContext) + -> &'tr Type { + self.safe_canonical_type(ctx) + .expect("Should have been resolved after parsing!") } /// Returns the canonical type of this type, that is, the "inner type". @@ -319,7 +316,9 @@ impl Type { /// For example, for a `typedef`, the canonical type would be the /// `typedef`ed type, for a template specialization, would be the template /// its specializing, and so on. Return None if the type is unresolved. - pub fn safe_canonical_type<'tr>(&'tr self, ctx: &'tr BindgenContext) -> Option<&'tr Type> { + pub fn safe_canonical_type<'tr>(&'tr self, + ctx: &'tr BindgenContext) + -> Option<&'tr Type> { match self.kind { TypeKind::Named(..) | TypeKind::Array(..) | @@ -337,8 +336,9 @@ impl Type { TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(_, inner) | TypeKind::TemplateAlias(inner, _) | - TypeKind::TemplateRef(inner, _) - => ctx.resolve_type(inner).safe_canonical_type(ctx), + TypeKind::TemplateRef(inner, _) => { + ctx.resolve_type(inner).safe_canonical_type(ctx) + } TypeKind::UnresolvedTypeRef(..) => None, } @@ -413,7 +413,10 @@ pub enum TypeKind { /// already known types, and are converted to ResolvedTypeRef. /// /// see tests/headers/typeref.hpp to see somewhere where this is a problem. - UnresolvedTypeRef(clang::Type, Option, /* parent_id */ Option), + UnresolvedTypeRef(clang::Type, + Option, + /* parent_id */ + Option), /// An indirection to another type. /// @@ -438,14 +441,14 @@ impl Type { TypeKind::Void => true, TypeKind::Comp(ref ci) => ci.is_unsized(ctx), TypeKind::Array(inner, size) => { - size == 0 || - ctx.resolve_type(inner).is_unsized(ctx) + size == 0 || ctx.resolve_type(inner).is_unsized(ctx) } TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(_, inner) | TypeKind::TemplateAlias(inner, _) | - TypeKind::TemplateRef(inner, _) - => ctx.resolve_type(inner).is_unsized(ctx), + TypeKind::TemplateRef(inner, _) => { + ctx.resolve_type(inner).is_unsized(ctx) + } TypeKind::Named(..) | TypeKind::Int(..) | TypeKind::Float(..) | @@ -456,8 +459,9 @@ impl Type { TypeKind::BlockPointer | TypeKind::Pointer(..) => false, - TypeKind::UnresolvedTypeRef(..) - => unreachable!("Should have been resolved after parsing!"), + TypeKind::UnresolvedTypeRef(..) => { + unreachable!("Should have been resolved after parsing!"); + } } } @@ -470,19 +474,29 @@ impl Type { ty: &clang::Type, location: Option, parent_id: Option, - ctx: &mut BindgenContext) -> Result, ParseError> { + ctx: &mut BindgenContext) + -> Result, ParseError> { use clangll::*; - if let Some(ty) = ctx.builtin_or_resolved_ty(potential_id, parent_id, - ty, location) { - debug!("{:?} already resolved: {:?}", ty, location); - return Ok(ParseResult::AlreadyResolved(ty)); + { + let already_resolved = + ctx.builtin_or_resolved_ty(potential_id, + parent_id, + ty, + location); + if let Some(ty) = already_resolved { + debug!("{:?} already resolved: {:?}", ty, location); + return Ok(ParseResult::AlreadyResolved(ty)); + } } let layout = ty.fallible_layout().ok(); let cursor = ty.declaration(); let mut name = cursor.spelling(); - debug!("from_clang_ty: {:?}, ty: {:?}, loc: {:?}", potential_id, ty, location); + debug!("from_clang_ty: {:?}, ty: {:?}, loc: {:?}", + potential_id, + ty, + location); debug!("currently_parsed_types: {:?}", ctx.currently_parsed_types); let canonical_ty = ty.canonical_type(); @@ -490,37 +504,40 @@ impl Type { CXType_Unexposed if *ty != canonical_ty && canonical_ty.kind() != CXType_Invalid => { debug!("Looking for canonical type: {:?}", canonical_ty); - return Self::from_clang_ty(potential_id, &canonical_ty, - location, parent_id, ctx); + return Self::from_clang_ty(potential_id, + &canonical_ty, + location, + parent_id, + ctx); } - CXType_Unexposed | - CXType_Invalid => { - // For some reason Clang doesn't give us any hint - // in some situations where we should generate a - // function pointer (see - // tests/headers/func_ptr_in_struct.h), so we do a - // guess here trying to see if it has a valid return - // type. + CXType_Unexposed | CXType_Invalid => { + // For some reason Clang doesn't give us any hint in some + // situations where we should generate a function pointer (see + // tests/headers/func_ptr_in_struct.h), so we do a guess here + // trying to see if it has a valid return type. if ty.ret_type().is_some() { - let signature = - try!(FunctionSig::from_ty(ty, &location.unwrap_or(cursor), ctx)); + let signature = try!(FunctionSig::from_ty(ty, + &location.unwrap_or(cursor), + ctx)); TypeKind::Function(signature) - // Same here, with template specialisations we can safely assume - // this is a Comp(..) + // Same here, with template specialisations we can safely + // assume this is a Comp(..) } else if ty.template_args().map_or(false, |x| x.len() > 0) { debug!("Template specialization: {:?}", ty); let complex = CompInfo::from_ty(potential_id, ty, location, ctx) - .expect("C'mon"); + .expect("C'mon"); TypeKind::Comp(complex) } else if let Some(location) = location { match location.kind() { CXCursor_ClassTemplatePartialSpecialization | CXCursor_ClassTemplate => { name = location.spelling(); - let complex = - CompInfo::from_ty(potential_id, ty, Some(location), ctx) - .expect("C'mon"); + let complex = CompInfo::from_ty(potential_id, + ty, + Some(location), + ctx) + .expect("C'mon"); TypeKind::Comp(complex) } CXCursor_TypeAliasTemplateDecl => { @@ -533,11 +550,13 @@ impl Type { location.visit(|cur, _| { match cur.kind() { CXCursor_TypeAliasDecl => { - debug_assert!(cur.cur_type().kind() == CXType_Typedef); - inner = Item::from_ty(&cur.cur_type(), - Some(*cur), - Some(potential_id), - ctx); + debug_assert!(cur.cur_type().kind() == + CXType_Typedef); + inner = + Item::from_ty(&cur.cur_type(), + Some(*cur), + Some(potential_id), + ctx); } CXCursor_TemplateTypeParameter => { // See the comment in src/ir/comp.rs @@ -550,11 +569,13 @@ impl Type { Item::from_ty(&cur.cur_type(), Some(*cur), Some(potential_id), - ctx).ok(); + ctx) + .ok(); let param = Item::named_type(cur.spelling(), default_type, - potential_id, ctx); + potential_id, + ctx); args.push(param); } _ => {} @@ -563,7 +584,8 @@ impl Type { }); if inner.is_err() { - error!("Failed to parse templated type alias {:?}", location); + error!("Failed to parse templated alias {:?}", + location); return Err(ParseError::Continue); } @@ -582,24 +604,37 @@ impl Type { } CXCursor_TemplateRef => { let referenced = location.referenced(); + let referenced_ty = referenced.cur_type(); + let referenced_declaration = + Some(referenced_ty.declaration()); + return Self::from_clang_ty(potential_id, - &referenced.cur_type(), - Some(referenced.cur_type().declaration()), + &referenced_ty, + referenced_declaration, parent_id, ctx); } CXCursor_TypeRef => { let referenced = location.referenced(); - return Ok(ParseResult::AlreadyResolved( - Item::from_ty_or_ref_with_id(potential_id, - referenced.cur_type(), - Some(referenced.cur_type().declaration()), - parent_id, - ctx))); + let referenced_ty = referenced.cur_type(); + let referenced_declaration = + Some(referenced_ty.declaration()); + + let item = + Item::from_ty_or_ref_with_id( + potential_id, + referenced_ty, + referenced_declaration, + parent_id, + ctx); + return Ok(ParseResult::AlreadyResolved(item)); } _ => { if ty.kind() == CXType_Unexposed { - warn!("Unexposed type {:?}, recursing inside, loc: {:?}", ty, location); + warn!("Unexposed type {:?}, recursing inside, \ + loc: {:?}", + ty, + location); return Err(ParseError::Recurse); } @@ -642,36 +677,39 @@ impl Type { // process of resolving them. CXType_MemberPointer | CXType_Pointer => { - let inner = - Item::from_ty_or_ref(ty.pointee_type(), location, - parent_id, ctx); + let inner = Item::from_ty_or_ref(ty.pointee_type(), + location, + parent_id, + ctx); TypeKind::Pointer(inner) } - CXType_BlockPointer => { - TypeKind::BlockPointer - } + CXType_BlockPointer => TypeKind::BlockPointer, // XXX: RValueReference is most likely wrong, but I don't think we // can even add bindings for that, so huh. CXType_RValueReference | CXType_LValueReference => { - let inner = - Item::from_ty_or_ref(ty.pointee_type(), location, - parent_id, ctx); + let inner = Item::from_ty_or_ref(ty.pointee_type(), + location, + parent_id, + ctx); TypeKind::Reference(inner) } // XXX DependentSizedArray is wrong CXType_VariableArray | CXType_DependentSizedArray | CXType_IncompleteArray => { - let inner = Item::from_ty(ty.elem_type().as_ref() - .expect("Not an appropriate type?"), - location, parent_id, ctx) - .expect("Not able to resolve array element?"); + let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(), + location, + parent_id, + ctx) + .expect("Not able to resolve array element?"); TypeKind::Pointer(inner) } CXType_FunctionNoProto | CXType_FunctionProto => { - let signature = try!(FunctionSig::from_ty(ty, &location.unwrap_or(cursor), ctx)); + let signature = try!(FunctionSig::from_ty(ty, + &location.unwrap_or(cursor), + ctx)); TypeKind::Function(signature) } CXType_Typedef => { @@ -681,13 +719,13 @@ impl Type { TypeKind::Alias(ty.spelling(), inner) } CXType_Enum => { - let enum_ = Enum::from_ty(ty, ctx) - .expect("Not an enum?"); + let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); TypeKind::Enum(enum_) } CXType_Record => { - let complex = CompInfo::from_ty(potential_id, ty, location, ctx) - .expect("Not a complex type?"); + let complex = + CompInfo::from_ty(potential_id, ty, location, ctx) + .expect("Not a complex type?"); TypeKind::Comp(complex) } // FIXME: We stub vectors as arrays since in 99% of the cases the @@ -697,25 +735,31 @@ impl Type { // That being said, that should be fixed eventually. CXType_Vector | CXType_ConstantArray => { - let inner = Item::from_ty(ty.elem_type().as_ref() - .expect("Not an appropriate type?"), - location, parent_id, ctx) - .expect("Not able to resolve array element?"); + let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(), + location, + parent_id, + ctx) + .expect("Not able to resolve array element?"); TypeKind::Array(inner, ty.num_elements().unwrap()) } - // A complex number is always a real and an imaginary part, so + // A complex number is always a real and an imaginary part, + // so // represent that as a two-item array. CXType_Complex => { - let inner = Item::from_ty(ty.elem_type().as_ref() - .expect("Not an appropriate type?"), - location, parent_id, ctx) - .expect("Not able to resolve array element?"); + let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(), + location, + parent_id, + ctx) + .expect("Not able to resolve array element?"); TypeKind::Array(inner, 2) } #[cfg(not(feature="llvm_stable"))] CXType_Elaborated => { - return Self::from_clang_ty(potential_id, &ty.named(), - location, parent_id, ctx); + return Self::from_clang_ty(potential_id, + &ty.named(), + location, + parent_id, + ctx); } _ => { error!("unsupported type {:?} at {:?}", ty, location); @@ -746,8 +790,9 @@ impl TypeCollector for Type { TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(_, inner) | TypeKind::Named(_, Some(inner)) | - TypeKind::ResolvedTypeRef(inner) - => inner.collect_types(context, types, &()), + TypeKind::ResolvedTypeRef(inner) => { + inner.collect_types(context, types, &()) + } TypeKind::TemplateRef(inner, ref template_args) => { inner.collect_types(context, types, &()); @@ -762,7 +807,7 @@ impl TypeCollector for Type { // FIXME: Pending types! ref other @ _ => { debug!("Ignoring: {:?}", other); - }, + } } } } diff --git a/src/ir/var.rs b/src/ir/var.rs index e9245e1a7e..216d818577 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -1,12 +1,12 @@ //! Intermediate representation of variables. -use super::item::{Item, ItemId}; +use clang; +use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use super::context::BindgenContext; -use super::ty::TypeKind; -use super::int::IntKind; use super::function::cursor_mangling; -use parse::{ClangItemParser, ClangSubItemParser, ParseResult, ParseError}; -use clang; +use super::int::IntKind; +use super::item::{Item, ItemId}; +use super::ty::TypeKind; /// A `Var` is our intermediate representation of a variable. #[derive(Debug)] @@ -30,7 +30,8 @@ impl Var { mangled: Option, ty: ItemId, val: Option, - is_const: bool) -> Var { + is_const: bool) + -> Var { assert!(!name.is_empty()); Var { name: name, @@ -69,13 +70,17 @@ impl Var { impl ClangSubItemParser for Var { fn parse(cursor: clang::Cursor, - context: &mut BindgenContext) -> Result, ParseError> { + ctx: &mut BindgenContext) + -> Result, ParseError> { use clangll::*; match cursor.kind() { CXCursor_MacroDefinition => { - let value = match parse_int_literal_tokens(&cursor, context.translation_unit()) { - None => return Err(ParseError::Continue), + let value = parse_int_literal_tokens(&cursor, + ctx.translation_unit()); + + let value = match value { Some(v) => v, + None => return Err(ParseError::Continue), }; let name = cursor.spelling(); @@ -84,21 +89,28 @@ impl ClangSubItemParser for Var { return Err(ParseError::Continue); } - if context.parsed_macro(&name) { + if ctx.parsed_macro(&name) { warn!("Duplicated macro definition: {}", name); return Err(ParseError::Continue); } - context.note_parsed_macro(name.clone()); + ctx.note_parsed_macro(name.clone()); let ty = if value < 0 { - Item::builtin_type(TypeKind::Int(IntKind::Int), true, context) - } else if value.abs() > u32::max_value() as i64 { - Item::builtin_type(TypeKind::Int(IntKind::ULongLong), true, context) + Item::builtin_type(TypeKind::Int(IntKind::Int), true, ctx) + } else if value.abs() > u32::max_value() as i64 { + Item::builtin_type(TypeKind::Int(IntKind::ULongLong), + true, + ctx) } else { - Item::builtin_type(TypeKind::Int(IntKind::UInt), true, context) + Item::builtin_type(TypeKind::Int(IntKind::UInt), true, ctx) }; - Ok(ParseResult::New(Var::new(name, None, ty, Some(value), true), Some(cursor))) + Ok(ParseResult::New(Var::new(name, + None, + ty, + Some(value), + true), + Some(cursor))) } CXCursor_VarDecl => { let name = cursor.spelling(); @@ -112,20 +124,19 @@ impl ClangSubItemParser for Var { // XXX this is redundant, remove! let is_const = ty.is_const(); - let ty = Item::from_ty(&ty, Some(cursor), None, context) - .expect("Unable to resolve constant type?"); + let ty = Item::from_ty(&ty, Some(cursor), None, ctx) + .expect("Unable to resolve constant type?"); // Note: Ty might not be totally resolved yet, see // tests/headers/inner_const.hpp // // That's fine because in that case we know it's not a literal. - let value = context.safe_resolve_type(ty) - .and_then(|t| t.safe_canonical_type(context)).and_then(|t| { - if t.is_integer() { - get_integer_literal_from_cursor(&cursor, context.translation_unit()) - } else { - None - } + let value = ctx.safe_resolve_type(ty) + .and_then(|t| t.safe_canonical_type(ctx)) + .and_then(|t| if t.is_integer() { Some(t) } else { None }) + .and_then(|_| { + get_integer_literal_from_cursor(&cursor, + ctx.translation_unit()) }); let mangling = cursor_mangling(&cursor); @@ -144,7 +155,8 @@ impl ClangSubItemParser for Var { /// Try and parse the immediately found tokens from an unit (if any) to integers fn parse_int_literal_tokens(cursor: &clang::Cursor, - unit: &clang::TranslationUnit) -> Option { + unit: &clang::TranslationUnit) + -> Option { use clangll::{CXToken_Literal, CXToken_Punctuation}; let tokens = match unit.tokens(cursor) { @@ -158,11 +170,11 @@ fn parse_int_literal_tokens(cursor: &clang::Cursor, match token.kind { CXToken_Punctuation if token.spelling == "-" => { negate = !negate; - }, + } CXToken_Literal => { literal = Some(token.spelling); - break - }, + break; + } _ => { // Reset values if we found anything else negate = false; @@ -172,21 +184,23 @@ fn parse_int_literal_tokens(cursor: &clang::Cursor, } literal.and_then(|lit| { - if lit.starts_with("0x") { - // TODO: try to preserve hex literals? - i64::from_str_radix(&lit[2..], 16).ok() - } else if lit == "0" { - Some(0) - } else if lit.starts_with("0") { - i64::from_str_radix(&lit[1..], 8).ok() - } else { - lit.parse().ok() - } - }).map(|lit| if negate { -lit } else { lit }) + if lit.starts_with("0x") { + // TODO: try to preserve hex literals? + i64::from_str_radix(&lit[2..], 16).ok() + } else if lit == "0" { + Some(0) + } else if lit.starts_with("0") { + i64::from_str_radix(&lit[1..], 8).ok() + } else { + lit.parse().ok() + } + }) + .map(|lit| if negate { -lit } else { lit }) } fn get_integer_literal_from_cursor(cursor: &clang::Cursor, - unit: &clang::TranslationUnit) -> Option { + unit: &clang::TranslationUnit) + -> Option { use clangll::*; let mut value = None; cursor.visit(|c, _| { @@ -198,7 +212,7 @@ fn get_integer_literal_from_cursor(cursor: &clang::Cursor, CXCursor_UnexposedExpr => { value = get_integer_literal_from_cursor(&c, unit); } - _ => () + _ => (), } if value.is_some() { CXChildVisit_Break diff --git a/src/lib.rs b/src/lib.rs index 19ecb6c9a3..1592c275df 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,44 +42,54 @@ extern crate lazy_static; // undocumented. Normal builds, however, will leave the module private, so that // we don't expose internals to library consumers. macro_rules! doc_mod { - ($m:ident) => { + ($m:ident, $doc_mod_name:ident) => { cfg_if! { if #[cfg(feature = "_docs")] { - pub mod $m; + pub mod $doc_mod_name { + //! Autogenerated documentation module. + pub use super::$m::*; + } } else { - mod $m; } } }; } mod clangll; -doc_mod!(clang); -doc_mod!(ir); -doc_mod!(parse); -doc_mod!(regex_set); +mod clang; +mod ir; +mod parse; +mod regex_set; + +#[cfg(rustfmt)] +mod codegen; + +doc_mod!(clang, clang_docs); +doc_mod!(ir, ir_docs); +doc_mod!(parse, parse_docs); +doc_mod!(regex_set, regex_set_docs); mod codegen { include!(concat!(env!("OUT_DIR"), "/codegen.rs")); } + +use ir::context::BindgenContext; +use ir::item::{Item, ItemId}; +use parse::{ClangItemParser, ParseError}; +use regex_set::RegexSet; use std::borrow::Borrow; -use std::io::{self, Write}; +use std::collections::HashSet; use std::fs::OpenOptions; +use std::io::{self, Write}; use std::path::Path; -use std::collections::HashSet; use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; -use syntax::print::pprust; use syntax::print::pp::eof; +use syntax::print::pprust; use syntax::ptr::P; -use ir::context::BindgenContext; -use ir::item::{Item, ItemId}; -use parse::{ClangItemParser, ParseError}; -use regex_set::RegexSet; - /// Configure and generate Rust bindings for a C/C++ header. /// /// This is the main entry point to the library. @@ -300,7 +310,7 @@ pub enum LinkType { /// Use static linking. Static, /// The library is an OSX framework. - Framework + Framework, } /// Generated Rust bindings. @@ -315,7 +325,9 @@ impl Bindings { /// /// Deprecated - use a `Builder` instead #[deprecated] - pub fn generate(options: BindgenOptions, span: Option) -> Result { + pub fn generate(options: BindgenOptions, + span: Option) + -> Result { let span = span.unwrap_or(DUMMY_SP); let mut context = BindgenContext::new(options); @@ -349,7 +361,11 @@ impl Bindings { /// Write these bindings as source text to a file. pub fn write_to_file>(&self, path: P) -> io::Result<()> { - let file = try!(OpenOptions::new().write(true).truncate(true).create(true).open(path)); + let file = try!(OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(path)); self.write(Box::new(file)) } @@ -357,7 +373,8 @@ impl Bindings { // https://github.com/Manishearth/rust-clippy/issues/740 #[cfg_attr(feature = "clippy", allow(needless_lifetimes))] pub fn write<'a>(&self, mut writer: Box) -> io::Result<()> { - 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.raw_lines.iter() { try!(writer.write(line.as_bytes())); @@ -390,15 +407,16 @@ fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool { pub fn parse_one(ctx: &mut BindgenContext, cursor: clang::Cursor, parent: Option, - children: &mut Vec) -> clangll::Enum_CXVisitorResult { + children: &mut Vec) + -> clangll::Enum_CXVisitorResult { if !filter_builtins(ctx, &cursor) { - return CXChildVisit_Continue + return CXChildVisit_Continue; } use clangll::CXChildVisit_Continue; match Item::parse(cursor, parent, ctx) { Ok(id) => children.push(id), - Err(ParseError::Continue) => {}, + Err(ParseError::Continue) => {} Err(ParseError::Recurse) => { cursor.visit(|child, _| parse_one(ctx, *child, parent, children)); } diff --git a/src/parse.rs b/src/parse.rs index 1f5566437f..98cf6b13e8 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,9 +1,9 @@ //! Common traits and types related to parsing our IR from Clang cursors. use clang; -use ir::ty::TypeKind; -use ir::item::ItemId; use ir::context::BindgenContext; +use ir::item::ItemId; +use ir::ty::TypeKind; /// Not so much an error in the traditional sense, but a control flow message /// when walking over Clang's AST with a cursor. @@ -30,12 +30,14 @@ pub enum ParseResult { /// An intermediate representation "sub-item" (i.e. one of the types contained /// inside an `ItemKind` variant) that can be parsed from a Clang cursor. -pub trait ClangSubItemParser : Sized { +pub trait ClangSubItemParser: Sized { /// Attempt to parse this type from the given cursor. /// /// The fact that is a reference guarantees it's held by the context, and /// allow returning already existing types. - fn parse(cursor: clang::Cursor, context: &mut BindgenContext) -> Result, ParseError>; + fn parse(cursor: clang::Cursor, + context: &mut BindgenContext) + -> Result, ParseError>; } /// An intermediate representation item that can be parsed from a Clang cursor. @@ -43,13 +45,15 @@ pub trait ClangItemParser: Sized { /// Parse this item from the given Clang cursor. fn parse(cursor: clang::Cursor, parent: Option, - context: &mut BindgenContext) -> Result; + context: &mut BindgenContext) + -> Result; /// Parse this item from the given Clang type. fn from_ty(ty: &clang::Type, location: Option, parent: Option, - ctx: &mut BindgenContext) -> Result; + ctx: &mut BindgenContext) + -> Result; /// Identical to `from_ty`, but use the given `id` as the `ItemId` for the /// newly parsed item. @@ -57,14 +61,16 @@ pub trait ClangItemParser: Sized { ty: &clang::Type, location: Option, parent: Option, - ctx: &mut BindgenContext) -> Result; + ctx: &mut BindgenContext) + -> Result; /// Parse this item from the given Clang type, or if we haven't resolved all /// the other items this one depends on, an unresolved reference. fn from_ty_or_ref(ty: clang::Type, location: Option, parent_id: Option, - context: &mut BindgenContext) -> ItemId; + context: &mut BindgenContext) + -> ItemId; /// Identical to `from_ty_or_ref`, but use the given `potential_id` as the /// `ItemId` for the newly parsed item. @@ -72,19 +78,30 @@ pub trait ClangItemParser: Sized { ty: clang::Type, location: Option, parent_id: Option, - context: &mut BindgenContext) -> ItemId; + context: &mut BindgenContext) + -> ItemId; /// Create a named template type. - fn named_type(name: S, default: Option, parent: ItemId, - context: &mut BindgenContext) -> ItemId + fn named_type(name: S, + default: Option, + parent: ItemId, + context: &mut BindgenContext) + -> ItemId where S: Into; /// Identical to `named_type`, but use `id` as the resulting item's /// `ItemId`. - fn named_type_with_id(id: ItemId, name: S, default: Option, - parent: ItemId, context: &mut BindgenContext) -> ItemId + fn named_type_with_id(id: ItemId, + name: S, + default: Option, + parent: ItemId, + context: &mut BindgenContext) + -> ItemId where S: Into; /// Create a builtin type. - fn builtin_type(kind: TypeKind, is_const: bool, context: &mut BindgenContext) -> ItemId; + fn builtin_type(kind: TypeKind, + is_const: bool, + context: &mut BindgenContext) + -> ItemId; } diff --git a/src/regex_set.rs b/src/regex_set.rs index ff899d78db..9313059023 100644 --- a/src/regex_set.rs +++ b/src/regex_set.rs @@ -1,7 +1,7 @@ //! A type that represents the union of a set of regular expressions. -use std::borrow::Borrow; use regex::Regex; +use std::borrow::Borrow; // Yeah, I'm aware this is sorta crappy, should be cheaper to compile a regex // ORing all the patterns, I guess... @@ -9,7 +9,7 @@ use regex::Regex; /// A dynamic set of regular expressions. #[derive(Debug)] pub struct RegexSet { - items: Vec + items: Vec, } impl RegexSet { @@ -20,7 +20,7 @@ impl RegexSet { /// Extend this set with every regex in the iterator. pub fn extend(&mut self, iter: I) - where I: IntoIterator + where I: IntoIterator, { for s in iter.into_iter() { self.insert(&s) @@ -29,7 +29,7 @@ impl RegexSet { /// Insert a new regex into this set. pub fn insert(&mut self, string: &S) - where S: Borrow + where S: Borrow, { let s = string.borrow(); match Regex::new(&format!("^{}$", s)) { @@ -44,7 +44,7 @@ impl RegexSet { /// Does the given `string` match any of the regexes in this set? pub fn matches(&self, string: &S) -> bool - where S: Borrow + where S: Borrow, { let s = string.borrow(); for r in &self.items {