diff options
-rw-r--r-- | README.md | 2 | ||||
-rwxr-xr-x | src/bin/bindgen.rs | 15 | ||||
-rwxr-xr-x | src/clang.rs | 302 | ||||
-rw-r--r-- | src/ir/comp.rs | 21 | ||||
-rw-r--r-- | src/ir/context.rs | 4 | ||||
-rw-r--r-- | src/ir/enum_ty.rs | 2 | ||||
-rw-r--r-- | src/ir/function.rs | 4 | ||||
-rw-r--r-- | src/ir/item.rs | 4 | ||||
-rw-r--r-- | src/ir/module.rs | 4 | ||||
-rw-r--r-- | src/ir/ty.rs | 6 | ||||
-rw-r--r-- | src/ir/var.rs | 2 | ||||
-rwxr-xr-x | src/lib.rs | 40 |
12 files changed, 110 insertions, 296 deletions
@@ -149,4 +149,4 @@ This mode isn't actively maintained, so no promises are made around it. Check out the upstream documentation for info about how it *should* work. [sm-script]: https://github.com/servo/rust-mozjs/blob/master/etc/bindings.sh -[stylo-scripts]: https://github.com/servo/servo/tree/master/ports/geckolib/gecko_bindings/tools +[stylo-scripts]: https://github.com/servo/servo/tree/master/components/style/binding_tools diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index 17385d85..2127ea49 100755 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -8,7 +8,7 @@ extern crate log; extern crate clang_sys; extern crate rustc_serialize; -use bindgen::{BindgenOptions, Bindings, LinkType}; +use bindgen::{BindgenOptions, Bindings, LinkType, ClangVersion, clang_version}; use std::default::Default; use std::env; use std::fs; @@ -232,6 +232,19 @@ pub fn main() { let mut bind_args: Vec<_> = env::args().collect(); + let version = clang_version(); + let expected_version = if cfg!(feature = "llvm_stable") { (3,8) } else { (3,9) }; + + info!("Clang Version: {}", version.full); + + match version.parsed { + None => warn!("Couldn't parse libclang version"), + Some(version) if version != expected_version => { + error!("Using clang {:?}, expected {:?}", version, expected_version); + } + _ => {} + } + if let Some(clang) = clang_sys::support::Clang::find(None) { let has_clang_args = bind_args.iter().rposition(|arg| *arg == "--").is_some(); diff --git a/src/clang.rs b/src/clang.rs index b58cf017..b335a585 100755 --- a/src/clang.rs +++ b/src/clang.rs @@ -31,14 +31,6 @@ impl fmt::Debug for Cursor { } } -/// A cursor visitor function. -/// -/// 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; - impl Cursor { /// Get the Unified Symbol Resolution for this cursor's referent, if /// available. @@ -190,7 +182,7 @@ impl Cursor { /// Is the referent a template specialization? pub fn is_template(&self) -> bool { - self.specialized().is_valid() + self.specialized().is_some() } /// Is the referent a fully specialized template specialization without any @@ -290,11 +282,12 @@ impl Cursor { /// Given that this cursor points to a template specialization, get a cursor /// pointing to the template definition that is being specialized. - pub fn specialized(&self) -> Cursor { + pub fn specialized(&self) -> Option<Cursor> { unsafe { - Cursor { - x: clang_getSpecializedCursorTemplate(self.x), - } + let ret = Cursor { + x: clang_getSpecializedCursorTemplate(self.x) + }; + if ret.is_valid() { Some(ret) } else { None } } } @@ -306,21 +299,14 @@ impl Cursor { /// Traverse this cursor's referent and its children. /// - /// Call the given function on each AST node traversed. See `CursorVisitor` - /// for details on arguments passed to the function and how its return value - /// is interpreted. - pub fn visit<F>(&self, func: F) - where F: for<'a, 'b> FnMut(&'a Cursor, &'b Cursor) - -> Enum_CXChildVisitResult, + /// Call the given function on each AST node traversed. + pub fn visit<Visitor>(&self, mut visitor: Visitor) + where Visitor: FnMut(Cursor) -> Enum_CXChildVisitResult, { - let mut data: Box<CursorVisitor> = Box::new(func); - 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)); + clang_visitChildren(self.x, + Some(visit_children::<Visitor>), + mem::transmute(&mut visitor)); } } @@ -484,17 +470,18 @@ impl Cursor { } } -extern "C" fn visit_children(cur: CXCursor, - parent: CXCursor, - data: CXClientData) - -> Enum_CXChildVisitResult { - let func: &mut Box<CursorVisitor> = unsafe { mem::transmute(data) }; - (*func)(&Cursor { - x: cur, - }, - &Cursor { - x: parent, - }) +extern "C" fn visit_children<Visitor>(cur: CXCursor, + _parent: CXCursor, + data: CXClientData) + -> Enum_CXChildVisitResult + where Visitor: FnMut(Cursor) -> Enum_CXChildVisitResult, +{ + let func: &mut Visitor = unsafe { mem::transmute(data) }; + let child = Cursor { + x: cur, + }; + + (*func)(child) } impl PartialEq for Cursor { @@ -1159,239 +1146,13 @@ impl UnsavedFile { } /// Convert a cursor kind into a static string. -pub fn kind_to_str(x: Enum_CXCursorKind) -> &'static str { - match x { - CXCursor_UnexposedDecl => "UnexposedDecl", - CXCursor_StructDecl => "StructDecl", - CXCursor_UnionDecl => "UnionDecl", - CXCursor_ClassDecl => "ClassDecl", - CXCursor_EnumDecl => "EnumDecl", - CXCursor_FieldDecl => "FieldDecl", - CXCursor_EnumConstantDecl => "EnumConstantDecl", - CXCursor_FunctionDecl => "FunctionDecl", - CXCursor_VarDecl => "VarDecl", - CXCursor_ParmDecl => "ParmDecl", - CXCursor_ObjCInterfaceDecl => "ObjCInterfaceDecl", - CXCursor_ObjCCategoryDecl => "ObjCCategoryDecl", - CXCursor_ObjCProtocolDecl => "ObjCProtocolDecl", - CXCursor_ObjCPropertyDecl => "ObjCPropertyDecl", - CXCursor_ObjCIvarDecl => "ObjCIvarDecl", - CXCursor_ObjCInstanceMethodDecl => "ObjCInstanceMethodDecl", - CXCursor_ObjCClassMethodDecl => "ObjCClassMethodDecl", - CXCursor_ObjCImplementationDecl => "ObjCImplementationDecl", - CXCursor_ObjCCategoryImplDecl => "ObjCCategoryImplDecl", - CXCursor_TypedefDecl => "TypedefDecl", - CXCursor_CXXMethod => "CXXMethod", - CXCursor_Namespace => "Namespace", - CXCursor_LinkageSpec => "LinkageSpec", - CXCursor_Constructor => "Constructor", - CXCursor_Destructor => "Destructor", - CXCursor_ConversionFunction => "ConversionFunction", - CXCursor_TemplateTypeParameter => "TemplateTypeParameter", - CXCursor_NonTypeTemplateParameter => "NonTypeTemplateParameter", - CXCursor_TemplateTemplateParameter => "TemplateTemplateParameter", - CXCursor_FunctionTemplate => "FunctionTemplate", - CXCursor_ClassTemplate => "ClassTemplate", - 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", - CXCursor_TypeAliasDecl => "TypeAliasDecl", - CXCursor_ObjCSynthesizeDecl => "ObjCSynthesizeDecl", - CXCursor_ObjCDynamicDecl => "ObjCDynamicDecl", - CXCursor_CXXAccessSpecifier => "CXXAccessSpecifier", - // CXCursor_FirstDecl => "FirstDecl", - // CXCursor_LastDecl => "LastDecl", - CXCursor_FirstRef => "FirstRef", - // CXCursor_ObjCSuperClassRef => "ObjCSuperClassRef", - CXCursor_ObjCProtocolRef => "ObjCProtocolRef", - CXCursor_ObjCClassRef => "ObjCClassRef", - CXCursor_TypeRef => "TypeRef", - CXCursor_CXXBaseSpecifier => "CXXBaseSpecifier", - CXCursor_TemplateRef => "TemplateRef", - CXCursor_NamespaceRef => "NamespaceRef", - CXCursor_MemberRef => "MemberRef", - // CXCursor_LabelRef => "LabelRef", - CXCursor_OverloadedDeclRef => "OverloadedDeclRef", - CXCursor_VariableRef => "VariableRef", - // CXCursor_LastRef => "LastRef", - CXCursor_FirstInvalid => "FirstInvalid", - // CXCursor_InvalidFile => "InvalidFile", - CXCursor_NoDeclFound => "NoDeclFound", - CXCursor_NotImplemented => "NotImplemented", - CXCursor_InvalidCode => "InvalidCode", - // CXCursor_LastInvalid => "LastInvalid", - CXCursor_FirstExpr => "FirstExpr", - // CXCursor_UnexposedExpr => "UnexposedExpr", - CXCursor_DeclRefExpr => "DeclRefExpr", - CXCursor_MemberRefExpr => "MemberRefExpr", - CXCursor_CallExpr => "CallExpr", - CXCursor_ObjCMessageExpr => "ObjCMessageExpr", - CXCursor_BlockExpr => "BlockExpr", - CXCursor_IntegerLiteral => "IntegerLiteral", - CXCursor_FloatingLiteral => "FloatingLiteral", - CXCursor_ImaginaryLiteral => "ImaginaryLiteral", - CXCursor_StringLiteral => "StringLiteral", - CXCursor_CharacterLiteral => "CharacterLiteral", - CXCursor_ParenExpr => "ParenExpr", - CXCursor_UnaryOperator => "UnaryOperator", - CXCursor_ArraySubscriptExpr => "ArraySubscriptExpr", - CXCursor_BinaryOperator => "BinaryOperator", - CXCursor_CompoundAssignOperator => "CompoundAssignOperator", - CXCursor_ConditionalOperator => "ConditionalOperator", - CXCursor_CStyleCastExpr => "CStyleCastExpr", - CXCursor_CompoundLiteralExpr => "CompoundLiteralExpr", - CXCursor_InitListExpr => "InitListExpr", - CXCursor_AddrLabelExpr => "AddrLabelExpr", - CXCursor_StmtExpr => "StmtExpr", - CXCursor_GenericSelectionExpr => "GenericSelectionExpr", - CXCursor_GNUNullExpr => "GNUNullExpr", - CXCursor_CXXStaticCastExpr => "CXXStaticCastExpr", - CXCursor_CXXDynamicCastExpr => "CXXDynamicCastExpr", - CXCursor_CXXReinterpretCastExpr => "CXXReinterpretCastExpr", - CXCursor_CXXConstCastExpr => "CXXConstCastExpr", - CXCursor_CXXFunctionalCastExpr => "CXXFunctionalCastExpr", - CXCursor_CXXTypeidExpr => "CXXTypeidExpr", - CXCursor_CXXBoolLiteralExpr => "CXXBoolLiteralExpr", - CXCursor_CXXNullPtrLiteralExpr => "CXXNullPtrLiteralExpr", - CXCursor_CXXThisExpr => "CXXThisExpr", - CXCursor_CXXThrowExpr => "CXXThrowExpr", - CXCursor_CXXNewExpr => "CXXNewExpr", - CXCursor_CXXDeleteExpr => "CXXDeleteExpr", - CXCursor_UnaryExpr => "UnaryExpr", - CXCursor_ObjCStringLiteral => "ObjCStringLiteral", - CXCursor_ObjCEncodeExpr => "ObjCEncodeExpr", - CXCursor_ObjCSelectorExpr => "ObjCSelectorExpr", - CXCursor_ObjCProtocolExpr => "ObjCProtocolExpr", - CXCursor_ObjCBridgedCastExpr => "ObjCBridgedCastExpr", - CXCursor_PackExpansionExpr => "PackExpansionExpr", - CXCursor_SizeOfPackExpr => "SizeOfPackExpr", - CXCursor_LambdaExpr => "LambdaExpr", - CXCursor_ObjCBoolLiteralExpr => "ObjCBoolLiteralExpr", - // CXCursor_LastExpr => "LastExpr", - CXCursor_FirstStmt => "FirstStmt", - // CXCursor_UnexposedStmt => "UnexposedStmt", - CXCursor_LabelStmt => "LabelStmt", - CXCursor_CompoundStmt => "CompoundStmt", - CXCursor_CaseStmt => "CaseStmt", - CXCursor_DefaultStmt => "DefaultStmt", - CXCursor_IfStmt => "IfStmt", - CXCursor_SwitchStmt => "SwitchStmt", - CXCursor_WhileStmt => "WhileStmt", - CXCursor_DoStmt => "DoStmt", - CXCursor_ForStmt => "ForStmt", - CXCursor_GotoStmt => "GotoStmt", - CXCursor_IndirectGotoStmt => "IndirectGotoStmt", - CXCursor_ContinueStmt => "ContinueStmt", - CXCursor_BreakStmt => "BreakStmt", - CXCursor_ReturnStmt => "ReturnStmt", - CXCursor_AsmStmt => "AsmStmt", - CXCursor_ObjCAtTryStmt => "ObjCAtTryStmt", - CXCursor_ObjCAtCatchStmt => "ObjCAtCatchStmt", - CXCursor_ObjCAtFinallyStmt => "ObjCAtFinallyStmt", - CXCursor_ObjCAtThrowStmt => "ObjCAtThrowStmt", - CXCursor_ObjCAtSynchronizedStmt => "ObjCAtSynchronizedStmt", - CXCursor_ObjCAutoreleasePoolStmt => "ObjCAutoreleasePoolStmt", - CXCursor_ObjCForCollectionStmt => "ObjCForCollectionStmt", - CXCursor_CXXCatchStmt => "CXXCatchStmt", - CXCursor_CXXTryStmt => "CXXTryStmt", - CXCursor_CXXForRangeStmt => "CXXForRangeStmt", - CXCursor_SEHTryStmt => "SEHTryStmt", - CXCursor_SEHExceptStmt => "SEHExceptStmt", - CXCursor_SEHFinallyStmt => "SEHFinallyStmt", - CXCursor_NullStmt => "NullStmt", - CXCursor_DeclStmt => "DeclStmt", - // CXCursor_LastStmt => "LastStmt", - CXCursor_TranslationUnit => "TranslationUnit", - CXCursor_FirstAttr => "FirstAttr", - // CXCursor_UnexposedAttr => "UnexposedAttr", - CXCursor_IBActionAttr => "IBActionAttr", - CXCursor_IBOutletAttr => "IBOutletAttr", - CXCursor_IBOutletCollectionAttr => "IBOutletCollectionAttr", - CXCursor_CXXFinalAttr => "CXXFinalAttr", - CXCursor_CXXOverrideAttr => "CXXOverrideAttr", - CXCursor_AnnotateAttr => "AnnotateAttr", - CXCursor_AsmLabelAttr => "AsmLabelAttr", - // CXCursor_LastAttr => "LastAttr", - CXCursor_PreprocessingDirective => "PreprocessingDirective", - CXCursor_MacroDefinition => "MacroDefinition", - CXCursor_MacroExpansion => "MacroExpansion", - // CXCursor_MacroInstantiation => "MacroInstantiation", - CXCursor_InclusionDirective => "InclusionDirective", - // CXCursor_FirstPreprocessing => "FirstPreprocessing", - // CXCursor_LastPreprocessing => "LastPreprocessing", - CXCursor_PackedAttr => "PackedAttr", - CXCursor_ModuleImportDecl => "ModuleImportDecl", - CXCursor_TypeAliasTemplateDecl => "TypeAliasTemplateDecl", - CXCursor_StaticAssert => "StaticAssert", - _ => "?", - } +pub fn kind_to_str(x: Enum_CXCursorKind) -> String { + unsafe { clang_getCursorKindSpelling(x) }.into() } /// Convert a type kind to a static string. -pub fn type_to_str(x: Enum_CXTypeKind) -> &'static str { - match x { - CXType_Invalid => "Invalid", - CXType_Unexposed => "Unexposed", - CXType_Void => "Void", - CXType_Bool => "Bool", - CXType_Char_U => "Char_U", - CXType_UChar => "UChar", - CXType_Char16 => "Char16", - CXType_Char32 => "Char32", - CXType_UShort => "UShort", - CXType_UInt => "UInt", - CXType_ULong => "ULong", - CXType_ULongLong => "ULongLong", - CXType_UInt128 => "UInt128", - CXType_Char_S => "Char_S", - CXType_SChar => "SChar", - CXType_WChar => "WChar", - CXType_Short => "Short", - CXType_Int => "Int", - CXType_Long => "Long", - CXType_LongLong => "LongLong", - CXType_Int128 => "Int128", - CXType_Float => "Float", - CXType_Double => "Double", - CXType_LongDouble => "LongDouble", - CXType_NullPtr => "NullPtr", - CXType_Overload => "Overload", - CXType_Dependent => "Dependent", - CXType_ObjCId => "ObjCId", - CXType_ObjCClass => "ObjCClass", - CXType_ObjCSel => "ObjCSel", - // CXType_FirstBuiltin => "FirstBuiltin", - // CXType_LastBuiltin => "LastBuiltin", - CXType_Complex => "Complex", - CXType_Pointer => "Pointer", - CXType_BlockPointer => "BlockPointer", - CXType_LValueReference => "LValueReference", - CXType_RValueReference => "RValueReference", - CXType_Record => "Record", - CXType_Enum => "Enum", - CXType_Typedef => "Typedef", - CXType_ObjCInterface => "ObjCInterface", - CXType_ObjCObjectPointer => "ObjCObjectPointer", - CXType_FunctionNoProto => "FunctionNoProto", - CXType_FunctionProto => "FunctionProto", - CXType_ConstantArray => "ConstantArray", - CXType_Vector => "Vector", - CXType_IncompleteArray => "IncompleteArray", - CXType_VariableArray => "VariableArray", - CXType_DependentSizedArray => "DependentSizedArray", - CXType_MemberPointer => "MemberPointer", - #[cfg(not(feature="llvm_stable"))] - CXType_Auto => "Auto", - #[cfg(not(feature="llvm_stable"))] - CXType_Elaborated => "Elaborated", - _ => "?", - } +pub fn type_to_str(x: Enum_CXTypeKind) -> String { + unsafe { clang_getTypeKindSpelling(x).into() } } /// Dump the Clang AST to stdout for debugging purposes. @@ -1410,7 +1171,12 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult { kind_to_str(c.kind()), c.spelling(), type_to_str(ct))); - c.visit(|s, _: &Cursor| ast_dump(s, depth + 1)); + c.visit(|s| ast_dump(&s, depth + 1)); print_indent(depth, ")"); CXChildVisit_Continue } + +/// Try to extract the clang version to a string +pub fn extract_clang_version() -> String { + unsafe { clang_getClangVersion().into() } +} diff --git a/src/ir/comp.rs b/src/ir/comp.rs index d55c24ca..41e5c3d3 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -512,10 +512,11 @@ impl CompInfo { } }; - ci.ref_template = Item::parse(cursor.specialized(), None, ctx).ok(); + ci.ref_template = cursor.specialized() + .and_then(|c| Item::parse(c, None, ctx).ok()); let mut maybe_anonymous_struct_field = None; - cursor.visit(|cur, _other| { + cursor.visit(|cur| { if cur.kind() != CXCursor_FieldDecl { if let Some((ty, _)) = maybe_anonymous_struct_field { let field = Field::new(None, ty, None, None, None, false); @@ -529,7 +530,7 @@ impl CompInfo { match maybe_anonymous_struct_field.take() { Some((ty, clang_ty)) => { let mut used = false; - cur.visit(|child, _| { + cur.visit(|child| { if child.cur_type() == clang_ty { used = true; } @@ -550,12 +551,12 @@ impl CompInfo { let bit_width = cur.bit_width(); let field_type = Item::from_ty_or_ref(cur.cur_type(), - Some(*cur), + Some(cur), Some(potential_id), ctx); let comment = cur.raw_comment(); - let annotations = Annotations::new(cur); + let annotations = Annotations::new(&cur); let name = cur.spelling(); let is_mutable = cursor.is_mutable_field(); @@ -575,7 +576,7 @@ impl CompInfo { ci.fields.push(field); // No we look for things like attributes and stuff. - cur.visit(|cur, _| { + cur.visit(|cur| { if cur.kind() == CXCursor_UnexposedAttr { ci.found_unknown_attr = true; } @@ -593,7 +594,7 @@ impl CompInfo { CXCursor_UnionDecl | CXCursor_ClassTemplate | CXCursor_ClassDecl => { - let inner = Item::parse(*cur, Some(potential_id), ctx) + let inner = Item::parse(cur, Some(potential_id), ctx) .expect("Inner ClassDecl"); if !ci.inner_types.contains(&inner) { ci.inner_types.push(inner); @@ -619,7 +620,7 @@ impl CompInfo { } let default_type = Item::from_ty(&cur.cur_type(), - Some(*cur), + Some(cur), Some(potential_id), ctx) .ok(); @@ -687,7 +688,7 @@ impl CompInfo { // NB: This gets us an owned `Function`, not a // `FunctionSig`. let method_signature = - Item::parse(*cur, Some(potential_id), ctx) + Item::parse(cur, Some(potential_id), ctx) .expect("CXXMethod"); let is_const = cur.method_is_const(); @@ -726,7 +727,7 @@ impl CompInfo { return CXChildVisit_Continue; } - let item = Item::parse(*cur, Some(potential_id), ctx) + let item = Item::parse(cur, Some(potential_id), ctx) .expect("VarDecl"); ci.inner_vars.push(item); } diff --git a/src/ir/context.rs b/src/ir/context.rs index 9ffb1b7a..c5c321c4 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -499,14 +499,14 @@ impl<'ctx> BindgenContext<'ctx> { use clangll::*; let mut args = vec![]; let mut found_invalid_template_ref = false; - location.visit(|c, _| { + location.visit(|c| { if c.kind() == CXCursor_TemplateRef && c.cur_type().kind() == CXType_Invalid { found_invalid_template_ref = true; } if c.kind() == CXCursor_TypeRef { let new_ty = Item::from_ty_or_ref(c.cur_type(), - Some(*c), + Some(c), Some(with_id), self); args.push(new_ty); diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index fd7dbb45..e78184e7 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -70,7 +70,7 @@ impl Enum { None => true, }; - declaration.visit(|cursor, _| { + declaration.visit(|cursor| { if cursor.kind() == CXCursor_EnumConstantDecl { let name = cursor.spelling(); let comment = cursor.raw_comment(); diff --git a/src/ir/function.rs b/src/ir/function.rs index c2e6ffd0..163e3039 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -167,10 +167,10 @@ impl FunctionSig { // For non-CXCursor_FunctionDecl, visiting the cursor's children // is the only reliable way to get parameter names. let mut args = vec![]; - cursor.visit(|c, _| { + cursor.visit(|c| { if c.kind() == CXCursor_ParmDecl { let ty = - Item::from_ty(&c.cur_type(), Some(*c), None, ctx) + Item::from_ty(&c.cur_type(), Some(c), None, ctx) .expect("ParmDecl?"); let name = c.spelling(); let name = diff --git a/src/ir/item.rs b/src/ir/item.rs index d986bb32..23090739 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -1016,11 +1016,11 @@ impl ClangItemParser for Item { assert_eq!(popped_decl, declaration_to_look_for); } - location.visit(|cur, _other| { + location.visit(|cur| { use clangll::*; result = Item::from_ty_with_id(id, ty, - Some(*cur), + Some(cur), parent_id, ctx); match result { diff --git a/src/ir/module.rs b/src/ir/module.rs index c582d3eb..42175b92 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -49,8 +49,8 @@ impl ClangSubItemParser for Module { 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) }) }); diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 4d26cdff..81212029 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -547,14 +547,14 @@ impl Type { let mut inner = Err(ParseError::Continue); let mut args = vec![]; - location.visit(|cur, _| { + 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(cur), Some(potential_id), ctx); } @@ -567,7 +567,7 @@ impl Type { let default_type = Item::from_ty(&cur.cur_type(), - Some(*cur), + Some(cur), Some(potential_id), ctx) .ok(); diff --git a/src/ir/var.rs b/src/ir/var.rs index 216d8185..33e56242 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -203,7 +203,7 @@ fn get_integer_literal_from_cursor(cursor: &clang::Cursor, -> Option<i64> { use clangll::*; let mut value = None; - cursor.visit(|c, _| { + cursor.visit(|c| { match c.kind() { CXCursor_IntegerLiteral | CXCursor_UnaryOperator => { @@ -461,7 +461,7 @@ pub fn parse_one(ctx: &mut BindgenContext, Ok(id) => children.push(id), Err(ParseError::Continue) => {} Err(ParseError::Recurse) => { - cursor.visit(|child, _| parse_one(ctx, *child, parent, children)); + cursor.visit(|child| parse_one(ctx, child, parent, children)); } } CXChildVisit_Continue @@ -480,14 +480,48 @@ fn parse(context: &mut BindgenContext) { let cursor = context.translation_unit().cursor(); if context.options().emit_ast { - cursor.visit(|cur, _| clang::ast_dump(cur, 0)); + cursor.visit(|cur| clang::ast_dump(&cur, 0)); } let root = context.root_module(); context.with_module(root, |context, children| { - cursor.visit(|cursor, _| parse_one(context, *cursor, None, children)) + cursor.visit(|cursor| parse_one(context, cursor, None, children)) }); assert!(context.current_module() == context.root_module(), "How did this happen?"); } + +/// Extracted Clang version data +#[derive(Debug)] +pub struct ClangVersion { + /// Major and minor semvar, if parsing was successful + pub parsed: Option<(u32,u32)>, + /// full version string + pub full: String, +} + +/// Get the major and the minor semvar numbers of Clang's version +pub fn clang_version() -> ClangVersion { + let raw_v: String = clang::extract_clang_version(); + let split_v: Option<Vec<&str>> = raw_v + .split_whitespace() + .nth(2) + .map(|v| v.split('.').collect()); + match split_v { + Some(v) => { + if v.len() >= 2 { + let maybe_major = v[0].parse::<u32>(); + let maybe_minor = v[1].parse::<u32>(); + match (maybe_major,maybe_minor) { + (Ok(major),Ok(minor)) => return ClangVersion { parsed: Some((major,minor)), full: raw_v.clone() }, + _ => {}, + } + } + }, + None => {}, + }; + ClangVersion { parsed: None, full: raw_v.clone() } +} + + |