dotfiles/vim/plugin/libclang.py
Frank Villaro-Dixon b9bac31d4a using stow nowe
2016-06-13 12:11:18 +02:00

794 lines
35 KiB
Python

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 :