from clang.cindex import * import vim import time import threading import os import shlex # Check if libclang is able to find the builtin include files. # # libclang sometimes fails to correctly locate its builtin include files. This # happens especially if libclang is not installed at a standard location. This # function checks if the builtin includes are available. def canFindBuiltinHeaders(index, args = []): flags = 0 currentFile = ("test.c", '#include "stddef.h"') try: tu = index.parse("test.c", args, [currentFile], flags) except TranslationUnitLoadError, e: return 0 return len(tu.diagnostics) == 0 # Derive path to clang builtin headers. # # This function tries to derive a path to clang's builtin header files. We are # just guessing, but the guess is very educated. In fact, we should be right # for all manual installations (the ones where the builtin header path problem # is very common) as well as a set of very common distributions. def getBuiltinHeaderPath(library_path): if os.path.isfile(library_path): library_path = os.path.dirname(library_path) knownPaths = [ library_path + "/../lib/clang", # default value library_path + "/../clang", # gentoo library_path + "/clang", # opensuse library_path + "/", # Google "/usr/lib64/clang", # x86_64 (openSUSE, Fedora) "/usr/lib/clang" ] for path in knownPaths: try: files = os.listdir(path) if len(files) >= 1: files = sorted(files) subDir = files[-1] else: subDir = '.' path = path + "/" + subDir + "/include/" arg = "-I" + path if canFindBuiltinHeaders(index, [arg]): return path except: pass return None def initClangComplete(clang_complete_flags, clang_compilation_database, \ library_path): global index debug = int(vim.eval("g:clang_debug")) == 1 if library_path: if os.path.isdir(library_path): Config.set_library_path(library_path) else: Config.set_library_file(library_path) Config.set_compatibility_check(False) try: index = Index.create() except Exception, e: if library_path: suggestion = "Are you sure '%s' contains libclang?" % library_path else: suggestion = "Consider setting g:clang_library_path." if debug: exception_msg = str(e) else: exception_msg = '' print '''Loading libclang failed, completion won't be available. %s %s ''' % (suggestion, exception_msg) return 0 global builtinHeaderPath builtinHeaderPath = None if not canFindBuiltinHeaders(index): builtinHeaderPath = getBuiltinHeaderPath(library_path) if not builtinHeaderPath: print "WARNING: libclang can not find the builtin includes." print " This will cause slow code completion." print " Please report the problem." global translationUnits translationUnits = dict() global complete_flags complete_flags = int(clang_complete_flags) global compilation_database if clang_compilation_database != '': compilation_database = CompilationDatabase.fromDirectory(clang_compilation_database) else: compilation_database = None global libclangLock libclangLock = threading.Lock() return 1 # Get a tuple (fileName, fileContent) for the file opened in the current # vim buffer. The fileContent contains the unsafed buffer content. def getCurrentFile(): file = "\n".join(vim.current.buffer[:] + ["\n"]) return (vim.current.buffer.name, file) class CodeCompleteTimer: def __init__(self, debug, file, line, column, params): self._debug = debug if not debug: return content = vim.current.line print " " print "libclang code completion" print "========================" print "Command: clang %s -fsyntax-only " % " ".join(params['args']), print "-Xclang -code-completion-at=%s:%d:%d %s" % (file, line, column, file) print "cwd: %s" % params['cwd'] print "File: %s" % file print "Line: %d, Column: %d" % (line, column) print " " print "%s" % content print " " current = time.time() self._start = current self._last = current self._events = [] def registerEvent(self, event): if not self._debug: return current = time.time() since_last = current - self._last self._last = current self._events.append((event, since_last)) def finish(self): if not self._debug: return overall = self._last - self._start for event in self._events: name, since_last = event percent = 1 / overall * since_last * 100 print "libclang code completion - %25s: %.3fs (%5.1f%%)" % \ (name, since_last, percent) print " " print "Overall: %.3f s" % overall print "========================" print " " def getCurrentTranslationUnit(args, currentFile, fileName, timer, update = False): tu = translationUnits.get(fileName) if tu != None: if update: tu.reparse([currentFile]) timer.registerEvent("Reparsing") return tu flags = TranslationUnit.PARSE_PRECOMPILED_PREAMBLE | \ TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD try: tu = index.parse(fileName, args, [currentFile], flags) timer.registerEvent("First parse") except TranslationUnitLoadError, e: return None translationUnits[fileName] = tu # Reparse to initialize the PCH cache even for auto completion # This should be done by index.parse(), however it is not. # So we need to reparse ourselves. tu.reparse([currentFile]) timer.registerEvent("Generate PCH cache") return tu def splitOptions(options): # Use python's shell command lexer to correctly split the list of options in # accordance with the POSIX standard return shlex.split(options) def getQuickFix(diagnostic): # Some diagnostics have no file, e.g. "too many errors emitted, stopping now" if diagnostic.location.file: filename = diagnostic.location.file.name else: filename = "" if diagnostic.severity == diagnostic.Ignored: type = 'I' elif diagnostic.severity == diagnostic.Note: type = 'I' elif diagnostic.severity == diagnostic.Warning: if "argument unused during compilation" in diagnostic.spelling: return None type = 'W' elif diagnostic.severity == diagnostic.Error: type = 'E' elif diagnostic.severity == diagnostic.Fatal: type = 'E' else: return None return dict({ 'bufnr' : int(vim.eval("bufnr('" + filename + "', 1)")), 'lnum' : diagnostic.location.line, 'col' : diagnostic.location.column, 'text' : diagnostic.spelling, 'type' : type}) def getQuickFixList(tu): return filter (None, map (getQuickFix, tu.diagnostics)) def highlightRange(range, hlGroup): pattern = '/\%' + str(range.start.line) + 'l' + '\%' \ + str(range.start.column) + 'c' + '.*' \ + '\%' + str(range.end.column) + 'c/' command = "exe 'syntax match' . ' " + hlGroup + ' ' + pattern + "'" vim.command(command) def highlightDiagnostic(diagnostic): if diagnostic.severity == diagnostic.Warning: hlGroup = 'SpellLocal' elif diagnostic.severity == diagnostic.Error: hlGroup = 'SpellBad' else: return pattern = '/\%' + str(diagnostic.location.line) + 'l\%' \ + str(diagnostic.location.column) + 'c./' command = "exe 'syntax match' . ' " + hlGroup + ' ' + pattern + "'" vim.command(command) for range in diagnostic.ranges: highlightRange(range, hlGroup) def highlightDiagnostics(tu): map (highlightDiagnostic, tu.diagnostics) def highlightCurrentDiagnostics(): if vim.current.buffer.name in translationUnits: highlightDiagnostics(translationUnits[vim.current.buffer.name]) def getCurrentQuickFixList(): if vim.current.buffer.name in translationUnits: return getQuickFixList(translationUnits[vim.current.buffer.name]) return [] # Get the compilation parameters from the compilation database for source # 'fileName'. The parameters are returned as map with the following keys : # # 'args' : compiler arguments. # Compilation database returns the complete command line. We need # to filter at least the compiler invocation, the '-o' + output # file, the input file and the '-c' arguments. We alter -I paths # to make them absolute, so that we can launch clang from wherever # we are. # Note : we behave differently from cc_args.py which only keeps # '-I', '-D' and '-include' options. # # 'cwd' : the compiler working directory # # The last found args and cwd are remembered and reused whenever a file is # not found in the compilation database. For example, this is the case for # all headers. This achieve very good results in practice. def getCompilationDBParams(fileName): if compilation_database: cmds = compilation_database.getCompileCommands(fileName) if cmds != None: cwd = cmds[0].directory args = [] skip_next = 1 # Skip compiler invocation for arg in cmds[0].arguments: if skip_next: skip_next = 0; continue if arg == '-c': continue if arg == fileName or \ os.path.realpath(os.path.join(cwd, arg)) == fileName: continue if arg == '-o': skip_next = 1; continue if arg.startswith('-I'): includePath = arg[2:] if not os.path.isabs(includePath): includePath = os.path.normpath(os.path.join(cwd, includePath)) args.append('-I'+includePath) continue args.append(arg) getCompilationDBParams.last_query = { 'args': args, 'cwd': cwd } # Do not directly return last_query, but make sure we return a deep copy. # Otherwise users of that result may accidently change it and store invalid # values in our cache. query = getCompilationDBParams.last_query return { 'args': list(query['args']), 'cwd': query['cwd']} getCompilationDBParams.last_query = { 'args': [], 'cwd': None } def getCompileParams(fileName): global builtinHeaderPath params = getCompilationDBParams(fileName) args = params['args'] args += splitOptions(vim.eval("g:clang_user_options")) args += splitOptions(vim.eval("b:clang_user_options")) args += splitOptions(vim.eval("b:clang_parameters")) if builtinHeaderPath: args.append("-I" + builtinHeaderPath) return { 'args' : args, 'cwd' : params['cwd'] } def updateCurrentDiagnostics(): global debug debug = int(vim.eval("g:clang_debug")) == 1 params = getCompileParams(vim.current.buffer.name) timer = CodeCompleteTimer(debug, vim.current.buffer.name, -1, -1, params) with libclangLock: getCurrentTranslationUnit(params['args'], getCurrentFile(), vim.current.buffer.name, timer, update = True) timer.finish() def getCurrentCompletionResults(line, column, args, currentFile, fileName, timer): tu = getCurrentTranslationUnit(args, currentFile, fileName, timer) timer.registerEvent("Get TU") if tu == None: return None cr = tu.codeComplete(fileName, line, column, [currentFile], complete_flags) timer.registerEvent("Code Complete") return cr def formatResult(result): completion = dict() returnValue = None abbr = "" word = "" info = "" place_markers_for_optional_args = int(vim.eval("g:clang_complete_optional_args_in_snippets")) == 1 def roll_out_optional(chunks): result = [] word = "" for chunk in chunks: if chunk.isKindInformative() or chunk.isKindResultType() or chunk.isKindTypedText(): continue word += chunk.spelling if chunk.isKindOptional(): result += roll_out_optional(chunk.string) return [word] + result for chunk in result.string: if chunk.isKindInformative(): continue if chunk.isKindResultType(): returnValue = chunk continue chunk_spelling = chunk.spelling if chunk.isKindTypedText(): abbr = chunk_spelling if chunk.isKindOptional(): for optional_arg in roll_out_optional(chunk.string): if place_markers_for_optional_args: word += snippetsFormatPlaceHolder(optional_arg) info += optional_arg + "=?" if chunk.isKindPlaceHolder(): word += snippetsFormatPlaceHolder(chunk_spelling) else: word += chunk_spelling info += chunk_spelling menu = info if returnValue: menu = returnValue.spelling + " " + menu completion['word'] = snippetsAddSnippet(info, word, abbr) completion['abbr'] = abbr completion['menu'] = menu completion['info'] = info completion['dup'] = 1 # Replace the number that represents a specific kind with a better # textual representation. completion['kind'] = kinds[result.cursorKind] return completion class CompleteThread(threading.Thread): def __init__(self, line, column, currentFile, fileName, params, timer): threading.Thread.__init__(self) # Complete threads are daemon threads. Python and consequently vim does not # wait for daemon threads to finish execution when existing itself. As # clang may compile for a while, we do not have to wait for the compilation # to finish before vim can quit. Before adding this flags, vim was hanging # for a couple of seconds before it exited. self.daemon = True self.line = line self.column = column self.currentFile = currentFile self.fileName = fileName self.result = None self.args = params['args'] self.cwd = params['cwd'] self.timer = timer def run(self): with libclangLock: if self.line == -1: # Warm up the caches. For this it is sufficient to get the # current translation unit. No need to retrieve completion # results. This short pause is necessary to allow vim to # initialize itself. Otherwise we would get: E293: block was # not locked The user does not see any delay, as we just pause # a background thread. time.sleep(0.1) getCurrentTranslationUnit(self.args, self.currentFile, self.fileName, self.timer) else: self.result = getCurrentCompletionResults(self.line, self.column, self.args, self.currentFile, self.fileName, self.timer) def WarmupCache(): params = getCompileParams(vim.current.buffer.name) timer = CodeCompleteTimer(0, "", -1, -1, params) t = CompleteThread(-1, -1, getCurrentFile(), vim.current.buffer.name, params, timer) t.start() def getCurrentCompletions(base): global debug debug = int(vim.eval("g:clang_debug")) == 1 sorting = vim.eval("g:clang_sort_algo") line, _ = vim.current.window.cursor column = int(vim.eval("b:col")) params = getCompileParams(vim.current.buffer.name) timer = CodeCompleteTimer(debug, vim.current.buffer.name, line, column, params) t = CompleteThread(line, column, getCurrentFile(), vim.current.buffer.name, params, timer) t.start() while t.isAlive(): t.join(0.01) cancel = int(vim.eval('complete_check()')) if cancel != 0: return (str([]), timer) cr = t.result if cr is None: print "Cannot parse this source file. The following arguments " \ + "are used for clang: " + " ".join(params['args']) return (str([]), timer) results = cr.results timer.registerEvent("Count # Results (%s)" % str(len(results))) if base != "": results = filter(lambda x: getAbbr(x.string).startswith(base), results) timer.registerEvent("Filter") if sorting == 'priority': getPriority = lambda x: x.string.priority results = sorted(results, None, getPriority) if sorting == 'alpha': getAbbrevation = lambda x: getAbbr(x.string).lower() results = sorted(results, None, getAbbrevation) timer.registerEvent("Sort") result = map(formatResult, results) timer.registerEvent("Format") return (str(result), timer) def getAbbr(strings): for chunks in strings: if chunks.isKindTypedText(): return chunks.spelling return "" def jumpToLocation(filename, line, column, preview): filenameEscaped = filename.replace(" ", "\\ ") if preview: command = "pedit +%d %s" % (line, filenameEscaped) elif filename != vim.current.buffer.name: command = "edit %s" % filenameEscaped else: command = "normal m'" try: vim.command(command) except: # For some unknown reason, whenever an exception occurs in # vim.command, vim goes crazy and output tons of useless python # errors, catch those. return if not preview: vim.current.window.cursor = (line, column - 1) def gotoDeclaration(preview=True): global debug debug = int(vim.eval("g:clang_debug")) == 1 params = getCompileParams(vim.current.buffer.name) line, col = vim.current.window.cursor timer = CodeCompleteTimer(debug, vim.current.buffer.name, line, col, params) with libclangLock: tu = getCurrentTranslationUnit(params['args'], getCurrentFile(), vim.current.buffer.name, timer, update = True) if tu is None: print "Couldn't get the TranslationUnit" return f = File.from_name(tu, vim.current.buffer.name) loc = SourceLocation.from_position(tu, f, line, col + 1) cursor = Cursor.from_location(tu, loc) defs = [cursor.get_definition(), cursor.referenced] for d in defs: if d is not None and loc != d.location: loc = d.location if loc.file is not None: jumpToLocation(loc.file.name, loc.line, loc.column, preview) break timer.finish() # Manually extracted from Index.h # Doing it by hand is long, error prone and horrible, we must find a way # to do that automatically. kinds = dict({ \ # Declarations \ 1 : 't', # CXCursor_UnexposedDecl (A declaration whose specific kind is not \ # exposed via this interface) \ 2 : 't', # CXCursor_StructDecl (A C or C++ struct) \ 3 : 't', # CXCursor_UnionDecl (A C or C++ union) \ 4 : 't', # CXCursor_ClassDecl (A C++ class) \ 5 : 't', # CXCursor_EnumDecl (An enumeration) \ 6 : 'm', # CXCursor_FieldDecl (A field (in C) or non-static data member \ # (in C++) in a struct, union, or C++ class) \ 7 : 'e', # CXCursor_EnumConstantDecl (An enumerator constant) \ 8 : 'f', # CXCursor_FunctionDecl (A function) \ 9 : 'v', # CXCursor_VarDecl (A variable) \ 10 : 'a', # CXCursor_ParmDecl (A function or method parameter) \ 11 : '11', # CXCursor_ObjCInterfaceDecl (An Objective-C @interface) \ 12 : '12', # CXCursor_ObjCCategoryDecl (An Objective-C @interface for a \ # category) \ 13 : '13', # CXCursor_ObjCProtocolDecl (An Objective-C @protocol declaration) \ 14 : '14', # CXCursor_ObjCPropertyDecl (An Objective-C @property declaration) \ 15 : '15', # CXCursor_ObjCIvarDecl (An Objective-C instance variable) \ 16 : '16', # CXCursor_ObjCInstanceMethodDecl (An Objective-C instance method) \ 17 : '17', # CXCursor_ObjCClassMethodDecl (An Objective-C class method) \ 18 : '18', # CXCursor_ObjCImplementationDec (An Objective-C @implementation) \ 19 : '19', # CXCursor_ObjCCategoryImplDecll (An Objective-C @implementation \ # for a category) \ 20 : 't', # CXCursor_TypedefDecl (A typedef) \ 21 : 'f', # CXCursor_CXXMethod (A C++ class method) \ 22 : 'n', # CXCursor_Namespace (A C++ namespace) \ 23 : '23', # CXCursor_LinkageSpec (A linkage specification, e.g. 'extern "C"') \ 24 : '+', # CXCursor_Constructor (A C++ constructor) \ 25 : '~', # CXCursor_Destructor (A C++ destructor) \ 26 : '26', # CXCursor_ConversionFunction (A C++ conversion function) \ 27 : 'a', # CXCursor_TemplateTypeParameter (A C++ template type parameter) \ 28 : 'a', # CXCursor_NonTypeTemplateParameter (A C++ non-type template \ # parameter) \ 29 : 'a', # CXCursor_TemplateTemplateParameter (A C++ template template \ # parameter) \ 30 : 'f', # CXCursor_FunctionTemplate (A C++ function template) \ 31 : 'p', # CXCursor_ClassTemplate (A C++ class template) \ 32 : '32', # CXCursor_ClassTemplatePartialSpecialization (A C++ class template \ # partial specialization) \ 33 : 'n', # CXCursor_NamespaceAlias (A C++ namespace alias declaration) \ 34 : '34', # CXCursor_UsingDirective (A C++ using directive) \ 35 : '35', # CXCursor_UsingDeclaration (A C++ using declaration) \ 36 : 't', # CXCursor_TypeAliasDecl (A C++ alias declaration) \ 37 : '37', # CXCursor_ObjCSynthesizeDecl (An Objective-C synthesize definition)\ 38 : '38', # CXCursor_ObjCDynamicDecl (An Objective-C dynamic definition) \ 39 : '39', # CXCursor_CXXAccessSpecifier (An access specifier) \ \ # References \ 40 : '40', # CXCursor_ObjCSuperClassRef \ 41 : '41', # CXCursor_ObjCProtocolRef \ 42 : '42', # CXCursor_ObjCClassRef \ 43 : '43', # CXCursor_TypeRef \ 44 : '44', # CXCursor_CXXBaseSpecifier \ 45 : '45', # CXCursor_TemplateRef (A reference to a class template, function \ # template, template template parameter, or class template partial \ # specialization) \ 46 : '46', # CXCursor_NamespaceRef (A reference to a namespace or namespace \ # alias) \ 47 : '47', # CXCursor_MemberRef (A reference to a member of a struct, union, \ # or class that occurs in some non-expression context, e.g., a \ # designated initializer) \ 48 : '48', # CXCursor_LabelRef (A reference to a labeled statement) \ 49 : '49', # CXCursor_OverloadedDeclRef (A reference to a set of overloaded \ # functions or function templates that has not yet been resolved to \ # a specific function or function template) \ 50 : '50', # CXCursor_VariableRef \ \ # Error conditions \ #70 : '70', # CXCursor_FirstInvalid \ 70 : '70', # CXCursor_InvalidFile \ 71 : '71', # CXCursor_NoDeclFound \ 72 : 'u', # CXCursor_NotImplemented \ 73 : '73', # CXCursor_InvalidCode \ \ # Expressions \ 100 : '100', # CXCursor_UnexposedExpr (An expression whose specific kind is \ # not exposed via this interface) \ 101 : '101', # CXCursor_DeclRefExpr (An expression that refers to some value \ # declaration, such as a function, varible, or enumerator) \ 102 : '102', # CXCursor_MemberRefExpr (An expression that refers to a member \ # of a struct, union, class, Objective-C class, etc) \ 103 : '103', # CXCursor_CallExpr (An expression that calls a function) \ 104 : '104', # CXCursor_ObjCMessageExpr (An expression that sends a message \ # to an Objective-C object or class) \ 105 : '105', # CXCursor_BlockExpr (An expression that represents a block \ # literal) \ 106 : '106', # CXCursor_IntegerLiteral (An integer literal) \ 107 : '107', # CXCursor_FloatingLiteral (A floating point number literal) \ 108 : '108', # CXCursor_ImaginaryLiteral (An imaginary number literal) \ 109 : '109', # CXCursor_StringLiteral (A string literal) \ 110 : '110', # CXCursor_CharacterLiteral (A character literal) \ 111 : '111', # CXCursor_ParenExpr (A parenthesized expression, e.g. "(1)") \ 112 : '112', # CXCursor_UnaryOperator (This represents the unary-expression's \ # (except sizeof and alignof)) \ 113 : '113', # CXCursor_ArraySubscriptExpr ([C99 6.5.2.1] Array Subscripting) \ 114 : '114', # CXCursor_BinaryOperator (A builtin binary operation expression \ # such as "x + y" or "x <= y") \ 115 : '115', # CXCursor_CompoundAssignOperator (Compound assignment such as \ # "+=") \ 116 : '116', # CXCursor_ConditionalOperator (The ?: ternary operator) \ 117 : '117', # CXCursor_CStyleCastExpr (An explicit cast in C (C99 6.5.4) or a\ # C-style cast in C++ (C++ [expr.cast]), which uses the syntax \ # (Type)expr) \ 118 : '118', # CXCursor_CompoundLiteralExpr ([C99 6.5.2.5]) \ 119 : '119', # CXCursor_InitListExpr (Describes an C or C++ initializer list) \ 120 : '120', # CXCursor_AddrLabelExpr (The GNU address of label extension, \ # representing &&label) \ 121 : '121', # CXCursor_StmtExpr (This is the GNU Statement Expression \ # extension: ({int X=4; X;}) \ 122 : '122', # CXCursor_GenericSelectionExpr (brief Represents a C11 generic \ # selection) \ 123 : '123', # CXCursor_GNUNullExpr (Implements the GNU __null extension) \ 124 : '124', # CXCursor_CXXStaticCastExpr (C++'s static_cast<> expression) \ 125 : '125', # CXCursor_CXXDynamicCastExpr (C++'s dynamic_cast<> expression) \ 126 : '126', # CXCursor_CXXReinterpretCastExpr (C++'s reinterpret_cast<> \ # expression) \ 127 : '127', # CXCursor_CXXConstCastExpr (C++'s const_cast<> expression) \ 128 : '128', # CXCursor_CXXFunctionalCastExpr (Represents an explicit C++ type\ # conversion that uses "functional" notion \ # (C++ [expr.type.conv])) \ 129 : '129', # CXCursor_CXXTypeidExpr (A C++ typeid expression \ # (C++ [expr.typeid])) \ 130 : '130', # CXCursor_CXXBoolLiteralExpr (brief [C++ 2.13.5] C++ Boolean \ # Literal) \ 131 : '131', # CXCursor_CXXNullPtrLiteralExpr ([C++0x 2.14.7] C++ Pointer \ # Literal) \ 132 : '132', # CXCursor_CXXThisExpr (Represents the "this" expression in C+) \ 133 : '133', # CXCursor_CXXThrowExpr ([C++ 15] C++ Throw Expression) \ 134 : '134', # CXCursor_CXXNewExpr (A new expression for memory allocation \ # and constructor calls) \ 135 : '135', # CXCursor_CXXDeleteExpr (A delete expression for memory \ # deallocation and destructor calls) \ 136 : '136', # CXCursor_UnaryExpr (A unary expression) \ 137 : '137', # CXCursor_ObjCStringLiteral (An Objective-C string literal \ # i.e. @"foo") \ 138 : '138', # CXCursor_ObjCEncodeExpr (An Objective-C \@encode expression) \ 139 : '139', # CXCursor_ObjCSelectorExpr (An Objective-C \@selector expression)\ 140 : '140', # CXCursor_ObjCProtocolExpr (An Objective-C \@protocol expression)\ 141 : '141', # CXCursor_ObjCBridgedCastExpr (An Objective-C "bridged" cast \ # expression, which casts between Objective-C pointers and C \ # pointers, transferring ownership in the process) \ 142 : '142', # CXCursor_PackExpansionExpr (Represents a C++0x pack expansion \ # that produces a sequence of expressions) \ 143 : '143', # CXCursor_SizeOfPackExpr (Represents an expression that computes\ # the length of a parameter pack) \ 144 : '144', # CXCursor_LambdaExpr (Represents a C++ lambda expression that \ # produces a local function object) \ 145 : '145', # CXCursor_ObjCBoolLiteralExpr (Objective-c Boolean Literal) \ \ # Statements \ 200 : '200', # CXCursor_UnexposedStmt (A statement whose specific kind is not \ # exposed via this interface) \ 201 : '201', # CXCursor_LabelStmt (A labelled statement in a function) \ 202 : '202', # CXCursor_CompoundStmt (A group of statements like \ # { stmt stmt }. \ 203 : '203', # CXCursor_CaseStmt (A case statment) \ 204 : '204', # CXCursor_DefaultStmt (A default statement) \ 205 : '205', # CXCursor_IfStmt (An if statemen) \ 206 : '206', # CXCursor_SwitchStmt (A switch statement) \ 207 : '207', # CXCursor_WhileStmt (A while statement) \ 208 : '208', # CXCursor_DoStmt (A do statement) \ 209 : '209', # CXCursor_ForStmt (A for statement) \ 210 : '210', # CXCursor_GotoStmt (A goto statement) \ 211 : '211', # CXCursor_IndirectGotoStmt (An indirect goto statement) \ 212 : '212', # CXCursor_ContinueStmt (A continue statement) \ 213 : '213', # CXCursor_BreakStmt (A break statement) \ 214 : '214', # CXCursor_ReturnStmt (A return statement) \ 215 : '215', # CXCursor_GCCAsmStmt (A GCC inline assembly statement extension)\ 216 : '216', # CXCursor_ObjCAtTryStmt (Objective-C's overall try-catch-finally\ # statement. \ 217 : '217', # CXCursor_ObjCAtCatchStmt (Objective-C's catch statement) \ 218 : '218', # CXCursor_ObjCAtFinallyStmt (Objective-C's finally statement) \ 219 : '219', # CXCursor_ObjCAtThrowStmt (Objective-C's throw statement) \ 220 : '220', # CXCursor_ObjCAtSynchronizedStmt (Objective-C's synchronized \ # statement) \ 221 : '221', # CXCursor_ObjCAutoreleasePoolStmt (Objective-C's autorelease \ # pool statement) \ 222 : '222', # CXCursor_ObjCForCollectionStmt (Objective-C's collection \ # statement) \ 223 : '223', # CXCursor_CXXCatchStmt (C++'s catch statement) \ 224 : '224', # CXCursor_CXXTryStmt (C++'s try statement) \ 225 : '225', # CXCursor_CXXForRangeStmt (C++'s for (* : *) statement) \ 226 : '226', # CXCursor_SEHTryStmt (Windows Structured Exception Handling's \ # try statement) \ 227 : '227', # CXCursor_SEHExceptStmt (Windows Structured Exception Handling's\ # except statement. \ 228 : '228', # CXCursor_SEHFinallyStmt (Windows Structured Exception \ # Handling's finally statement) \ 229 : '229', # CXCursor_MSAsmStmt (A MS inline assembly statement extension) \ 230 : '230', # CXCursor_NullStmt (The null satement ";": C99 6.8.3p3) \ 231 : '231', # CXCursor_DeclStmt (Adaptor class for mixing declarations with \ # statements and expressions) \ \ # Translation unit \ 300 : '300', # CXCursor_TranslationUnit (Cursor that represents the \ # translation unit itself) \ \ # Attributes \ 400 : '400', # CXCursor_UnexposedAttr (An attribute whose specific kind is \ # not exposed via this interface) \ 401 : '401', # CXCursor_IBActionAttr \ 402 : '402', # CXCursor_IBOutletAttr \ 403 : '403', # CXCursor_IBOutletCollectionAttr \ 404 : '404', # CXCursor_CXXFinalAttr \ 405 : '405', # CXCursor_CXXOverrideAttr \ 406 : '406', # CXCursor_AnnotateAttr \ 407 : '407', # CXCursor_AsmLabelAttr \ \ # Preprocessing \ 500 : '500', # CXCursor_PreprocessingDirective \ 501 : 'd', # CXCursor_MacroDefinition \ 502 : '502', # CXCursor_MacroInstantiation \ 503 : '503', # CXCursor_InclusionDirective \ \ # Modules \ 600 : '600', # CXCursor_ModuleImportDecl (A module import declaration) \ }) # vim: set ts=2 sts=2 sw=2 expandtab :