| #![allow(non_uppercase_statics)] |
| |
| use libc::{c_uint, c_char, c_int, c_ulong}; |
| use std::{mem, io, ptr, string}; |
| use std::fmt; |
| use std::hash::Hash; |
| use std::hash::sip::SipState; |
| use std::c_str::CString; |
| |
| pub use clangll as ll; |
| use clangll::*; |
| |
| // Cursor |
| pub struct Cursor { |
| x: CXCursor |
| } |
| |
| pub type CursorVisitor<'s> = |c: &Cursor, p: &Cursor|: 's -> Enum_CXChildVisitResult; |
| |
| impl Cursor { |
| // common |
| pub fn spelling(&self) -> String { |
| unsafe { |
| String_ { x: clang_getCursorSpelling(self.x) }.to_string() |
| } |
| } |
| |
| pub fn kind(&self) -> Enum_CXCursorKind { |
| unsafe { |
| clang_getCursorKind(self.x) |
| } |
| } |
| |
| pub fn location(&self) -> SourceLocation { |
| unsafe { |
| SourceLocation { x: clang_getCursorLocation(self.x) } |
| } |
| } |
| |
| pub fn cur_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getCursorType(self.x) } |
| } |
| } |
| |
| pub fn definition(&self) -> Cursor { |
| unsafe { |
| Cursor { x: clang_getCursorDefinition(self.x) } |
| } |
| } |
| |
| pub fn visit(&self, func: CursorVisitor) { |
| unsafe { |
| let data = mem::transmute::<&CursorVisitor, CXClientData>(&func); |
| clang_visitChildren(self.x, Some(visit_children), data); |
| }; |
| } |
| |
| // bitfield |
| pub fn bit_width(&self) -> Option<uint> { |
| unsafe { |
| let w = clang_getFieldDeclBitWidth(self.x); |
| if w == -1 { |
| None |
| } else { |
| Some(w as uint) |
| } |
| } |
| } |
| |
| // enum |
| pub fn enum_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getEnumDeclIntegerType(self.x) } |
| } |
| } |
| |
| pub fn enum_val(&self) -> i64 { |
| unsafe { |
| clang_getEnumConstantDeclValue(self.x) as i64 |
| } |
| } |
| |
| // typedef |
| pub fn typedef_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getTypedefDeclUnderlyingType(self.x) } |
| } |
| } |
| |
| // function, variable |
| pub fn linkage(&self) -> Enum_CXLinkageKind { |
| unsafe { |
| clang_getCursorLinkage(self.x) |
| } |
| } |
| |
| // function |
| pub fn args(&self) -> Vec<Cursor> { |
| unsafe { |
| let num = self.num_args() as uint; |
| let mut args = vec!(); |
| for i in range(0, num) { |
| args.push(Cursor { x: clang_Cursor_getArgument(self.x, i as c_uint) }); |
| } |
| return args; |
| } |
| } |
| |
| pub fn ret_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getCursorResultType(self.x) } |
| } |
| } |
| |
| pub fn num_args(&self) -> i32 { |
| unsafe { |
| clang_Cursor_getNumArguments(self.x) |
| } |
| } |
| } |
| |
| extern fn visit_children(cur: CXCursor, parent: ll::CXCursor, |
| data: CXClientData) -> ll::Enum_CXChildVisitResult { |
| unsafe { |
| let func = mem::transmute::<CXClientData, &mut CursorVisitor>(data); |
| return (*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 |
| } |
| } |
| |
| fn ne(&self, other: &Cursor) -> bool { |
| return !self.eq(other); |
| } |
| } |
| |
| impl Eq for Cursor {} |
| |
| impl Hash for Cursor { |
| fn hash(&self, state: &mut SipState) { |
| self.x.kind.hash(state); |
| self.x.xdata.hash(state); |
| self.x.data[0].hash(state); |
| self.x.data[1].hash(state); |
| self.x.data[2].hash(state); |
| } |
| } |
| |
| // type |
| pub struct Type { |
| x: CXType |
| } |
| |
| impl Type { |
| // common |
| pub fn kind(&self) -> Enum_CXTypeKind { |
| return self.x.kind; |
| } |
| |
| pub fn declaration(&self) -> Cursor { |
| unsafe { |
| Cursor { x: clang_getTypeDeclaration(self.x) } |
| } |
| } |
| |
| pub fn is_const(&self) -> bool { |
| unsafe { |
| clang_isConstQualifiedType(self.x) == 1 |
| } |
| } |
| |
| pub fn size(&self) -> uint { |
| unsafe { |
| let val = clang_Type_getSizeOf(self.x); |
| if val < 0 { 0 } else { val as uint } |
| } |
| } |
| |
| pub fn align(&self) -> uint { |
| unsafe { |
| let val = clang_Type_getAlignOf(self.x); |
| if val < 0 { 0 } else { val as uint } |
| } |
| } |
| |
| // pointer |
| pub fn pointee_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getPointeeType(self.x) } |
| } |
| } |
| |
| // array |
| pub fn elem_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getArrayElementType(self.x) } |
| } |
| } |
| |
| pub fn array_size(&self) -> uint { |
| unsafe { |
| clang_getArraySize(self.x) as uint |
| } |
| } |
| |
| // typedef |
| pub fn canonical_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getCanonicalType(self.x) } |
| } |
| } |
| |
| // function |
| pub fn is_variadic(&self) -> bool { |
| unsafe { |
| clang_isFunctionTypeVariadic(self.x) == 1 |
| } |
| } |
| |
| pub fn arg_types(&self) -> Vec<Type> { |
| unsafe { |
| let num = clang_getNumArgTypes(self.x) as uint; |
| let mut args = vec!(); |
| for i in range(0, num) { |
| args.push(Type { x: clang_getArgType(self.x, i as c_uint) }); |
| } |
| return args; |
| } |
| } |
| |
| pub fn ret_type(&self) -> Type { |
| unsafe { |
| Type { x: clang_getResultType(self.x) } |
| } |
| } |
| } |
| |
| // SourceLocation |
| pub struct SourceLocation { |
| x: CXSourceLocation |
| } |
| |
| impl SourceLocation { |
| pub fn location(&self) -> (File, uint, uint, uint) { |
| unsafe { |
| let mut file = ptr::null_mut(); |
| let mut line = 0; |
| let mut col = 0; |
| let mut off = 0; |
| clang_getSpellingLocation(self.x, &mut file, &mut line, &mut col, &mut off); |
| return (File { x: file }, line as uint, col as uint, off as uint); |
| } |
| } |
| } |
| |
| impl fmt::Show for SourceLocation { |
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| let (file, line, col, _) = self.location(); |
| match file.is_null() { |
| false => { |
| try!(file.name().fmt(f)); |
| try!(":".fmt(f)); |
| try!(line.fmt(f)); |
| try!(":".fmt(f)); |
| col.fmt(f) |
| }, |
| true => "builtin definitions".fmt(f) |
| } |
| } |
| } |
| |
| // File |
| pub struct File { |
| x: CXFile |
| } |
| |
| impl File { |
| pub fn name(&self) -> String { |
| if self.is_null() { |
| return "".to_string(); |
| } |
| unsafe { |
| String_ { x: clang_getFileName(self.x) }.to_string() |
| } |
| } |
| |
| pub fn is_null(&self) -> bool { |
| self.x.is_null() |
| } |
| } |
| |
| // String |
| pub struct String_ { |
| x: CXString |
| } |
| |
| impl fmt::Show for String_ { |
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| if self.x.data.is_null() { |
| return "".fmt(f); |
| } |
| unsafe { |
| let c_str = clang_getCString(self.x) as *const c_char; |
| string::raw::from_buf(c_str as *const u8).fmt(f) |
| } |
| } |
| } |
| |
| // Index |
| pub struct Index { |
| x: CXIndex |
| } |
| |
| impl Index { |
| pub fn create(pch: bool, diag: bool) -> Index { |
| unsafe { |
| Index { x: clang_createIndex(pch as c_int, diag as c_int) } |
| } |
| } |
| |
| pub fn dispose(&self) { |
| unsafe { |
| clang_disposeIndex(self.x); |
| } |
| } |
| |
| pub fn is_null(&self) -> bool { |
| self.x.is_null() |
| } |
| } |
| |
| // TranslationUnit |
| pub struct TranslationUnit { |
| x: CXTranslationUnit |
| } |
| |
| impl TranslationUnit { |
| pub fn parse(ix: &Index, file: &str, cmd_args: &[String], |
| unsaved: &[UnsavedFile], opts: uint) -> TranslationUnit { |
| let _fname = file.to_c_str(); |
| let fname = _fname.as_ptr(); |
| let _c_args: Vec<CString> = cmd_args.iter().map(|s| s.to_c_str()).collect(); |
| let c_args: Vec<*const c_char> = _c_args.iter().map(|s| s.as_ptr()).collect(); |
| let mut c_unsaved: Vec<Struct_CXUnsavedFile> = unsaved.iter().map(|f| f.x).collect(); |
| let tu = unsafe { |
| clang_parseTranslationUnit(ix.x, fname, |
| c_args.as_ptr(), |
| c_args.len() as c_int, |
| c_unsaved.as_mut_ptr(), |
| c_unsaved.len() as c_uint, |
| opts as c_uint) |
| }; |
| TranslationUnit { x: tu } |
| } |
| |
| pub fn reparse(&self, unsaved: &[UnsavedFile], opts: uint) -> bool { |
| let mut c_unsaved: Vec<Struct_CXUnsavedFile> = unsaved.iter().map(|f| f.x).collect(); |
| |
| unsafe { |
| clang_reparseTranslationUnit(self.x, |
| c_unsaved.len() as c_uint, |
| c_unsaved.as_mut_ptr(), |
| opts as c_uint) == 0 |
| } |
| } |
| |
| pub fn diags(&self) -> Vec<Diagnostic> { |
| unsafe { |
| let num = clang_getNumDiagnostics(self.x) as uint; |
| let mut diags = vec!(); |
| for i in range(0, num) { |
| diags.push(Diagnostic { x: clang_getDiagnostic(self.x, i as c_uint) }); |
| } |
| return diags; |
| } |
| } |
| |
| pub fn cursor(&self) -> Cursor { |
| unsafe { |
| Cursor { x: clang_getTranslationUnitCursor(self.x) } |
| } |
| } |
| |
| pub fn dispose(&self) { |
| unsafe { |
| clang_disposeTranslationUnit(self.x); |
| } |
| } |
| |
| pub fn is_null(&self) -> bool { |
| self.x.is_null() |
| } |
| } |
| |
| // Diagnostic |
| pub struct Diagnostic { |
| x: CXDiagnostic |
| } |
| |
| impl Diagnostic { |
| pub fn default_opts() -> uint { |
| unsafe { |
| clang_defaultDiagnosticDisplayOptions() as uint |
| } |
| } |
| |
| pub fn format(&self, opts: uint) -> String { |
| unsafe { |
| String_ { x: clang_formatDiagnostic(self.x, opts as c_uint) }.to_string() |
| } |
| } |
| |
| pub fn severity(&self) -> Enum_CXDiagnosticSeverity { |
| unsafe { |
| clang_getDiagnosticSeverity(self.x) |
| } |
| } |
| |
| pub fn dispose(&self) { |
| unsafe { |
| clang_disposeDiagnostic(self.x); |
| } |
| } |
| } |
| |
| // UnsavedFile |
| pub struct UnsavedFile { |
| x: Struct_CXUnsavedFile, |
| name: CString, |
| contents: CString |
| } |
| |
| impl UnsavedFile { |
| pub fn new(name: &str, contents: &str) -> UnsavedFile { |
| let name = name.to_c_str(); |
| let contents = contents.to_c_str(); |
| let x = Struct_CXUnsavedFile { |
| Filename: name.as_ptr(), |
| Contents: contents.as_ptr(), |
| Length: contents.len() as c_ulong, |
| }; |
| UnsavedFile { |
| x: x, |
| name: name, |
| contents: contents |
| } |
| } |
| } |
| |
| 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 => "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", |
| |
| _ => "?", |
| } |
| } |
| |
| 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", |
| _ => "?" |
| } |
| } |
| |
| // Debug |
| pub fn ast_dump(c: &Cursor, depth: int)-> Enum_CXVisitorResult { |
| fn print_indent(depth: int, s: &str) { |
| let mut i = 0; |
| while i < depth { |
| io::print("\t"); |
| i += 1; |
| } |
| io::println(s); |
| } |
| let ct = c.cur_type().kind(); |
| print_indent(depth, format!("({} {} {}", |
| kind_to_str(c.kind()).as_slice(), |
| c.spelling().as_slice(), |
| type_to_str(ct)).as_slice() |
| ); |
| c.visit(|s, _| { |
| ast_dump(s, depth + 1) |
| }); |
| print_indent(depth, ")"); |
| return CXChildVisit_Continue; |
| } |