mirror of https://github.com/axmolengine/axmol.git
2551 lines
82 KiB
Python
2551 lines
82 KiB
Python
|
#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
|
||
|
#
|
||
|
# The LLVM Compiler Infrastructure
|
||
|
#
|
||
|
# This file is distributed under the University of Illinois Open Source
|
||
|
# License. See LICENSE.TXT for details.
|
||
|
#
|
||
|
#===------------------------------------------------------------------------===#
|
||
|
|
||
|
r"""
|
||
|
Clang Indexing Library Bindings
|
||
|
===============================
|
||
|
|
||
|
This module provides an interface to the Clang indexing library. It is a
|
||
|
low-level interface to the indexing library which attempts to match the Clang
|
||
|
API directly while also being "pythonic". Notable differences from the C API
|
||
|
are:
|
||
|
|
||
|
* string results are returned as Python strings, not CXString objects.
|
||
|
|
||
|
* null cursors are translated to None.
|
||
|
|
||
|
* access to child cursors is done via iteration, not visitation.
|
||
|
|
||
|
The major indexing objects are:
|
||
|
|
||
|
Index
|
||
|
|
||
|
The top-level object which manages some global library state.
|
||
|
|
||
|
TranslationUnit
|
||
|
|
||
|
High-level object encapsulating the AST for a single translation unit. These
|
||
|
can be loaded from .ast files or parsed on the fly.
|
||
|
|
||
|
Cursor
|
||
|
|
||
|
Generic object for representing a node in the AST.
|
||
|
|
||
|
SourceRange, SourceLocation, and File
|
||
|
|
||
|
Objects representing information about the input source.
|
||
|
|
||
|
Most object information is exposed using properties, when the underlying API
|
||
|
call is efficient.
|
||
|
"""
|
||
|
|
||
|
# TODO
|
||
|
# ====
|
||
|
#
|
||
|
# o API support for invalid translation units. Currently we can't even get the
|
||
|
# diagnostics on failure because they refer to locations in an object that
|
||
|
# will have been invalidated.
|
||
|
#
|
||
|
# o fix memory management issues (currently client must hold on to index and
|
||
|
# translation unit, or risk crashes).
|
||
|
#
|
||
|
# o expose code completion APIs.
|
||
|
#
|
||
|
# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
|
||
|
# clearly, and hide from the external interface (i.e., help(cindex)).
|
||
|
#
|
||
|
# o implement additional SourceLocation, SourceRange, and File methods.
|
||
|
|
||
|
from ctypes import *
|
||
|
import collections
|
||
|
|
||
|
def get_cindex_library():
|
||
|
# FIXME: It's probably not the case that the library is actually found in
|
||
|
# this location. We need a better system of identifying and loading the
|
||
|
# CIndex library. It could be on path or elsewhere, or versioned, etc.
|
||
|
import platform
|
||
|
name = platform.system()
|
||
|
if name == 'Darwin':
|
||
|
return cdll.LoadLibrary('libclang.dylib')
|
||
|
elif name == 'Windows':
|
||
|
return cdll.LoadLibrary('libclang.dll')
|
||
|
else:
|
||
|
return cdll.LoadLibrary('libclang.so')
|
||
|
|
||
|
# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
|
||
|
# object. This is a problem, because it means that from_parameter will see an
|
||
|
# integer and pass the wrong value on platforms where int != void*. Work around
|
||
|
# this by marshalling object arguments as void**.
|
||
|
c_object_p = POINTER(c_void_p)
|
||
|
|
||
|
lib = get_cindex_library()
|
||
|
|
||
|
### Exception Classes ###
|
||
|
|
||
|
class TranslationUnitLoadError(Exception):
|
||
|
"""Represents an error that occurred when loading a TranslationUnit.
|
||
|
|
||
|
This is raised in the case where a TranslationUnit could not be
|
||
|
instantiated due to failure in the libclang library.
|
||
|
|
||
|
FIXME: Make libclang expose additional error information in this scenario.
|
||
|
"""
|
||
|
pass
|
||
|
|
||
|
class TranslationUnitSaveError(Exception):
|
||
|
"""Represents an error that occurred when saving a TranslationUnit.
|
||
|
|
||
|
Each error has associated with it an enumerated value, accessible under
|
||
|
e.save_error. Consumers can compare the value with one of the ERROR_
|
||
|
constants in this class.
|
||
|
"""
|
||
|
|
||
|
# Indicates that an unknown error occurred. This typically indicates that
|
||
|
# I/O failed during save.
|
||
|
ERROR_UNKNOWN = 1
|
||
|
|
||
|
# Indicates that errors during translation prevented saving. The errors
|
||
|
# should be available via the TranslationUnit's diagnostics.
|
||
|
ERROR_TRANSLATION_ERRORS = 2
|
||
|
|
||
|
# Indicates that the translation unit was somehow invalid.
|
||
|
ERROR_INVALID_TU = 3
|
||
|
|
||
|
def __init__(self, enumeration, message):
|
||
|
assert isinstance(enumeration, int)
|
||
|
|
||
|
if enumeration < 1 or enumeration > 3:
|
||
|
raise Exception("Encountered undefined TranslationUnit save error "
|
||
|
"constant: %d. Please file a bug to have this "
|
||
|
"value supported." % enumeration)
|
||
|
|
||
|
self.save_error = enumeration
|
||
|
Exception.__init__(self, 'Error %d: %s' % (enumeration, message))
|
||
|
|
||
|
### Structures and Utility Classes ###
|
||
|
|
||
|
class _CXString(Structure):
|
||
|
"""Helper for transforming CXString results."""
|
||
|
|
||
|
_fields_ = [("spelling", c_char_p), ("free", c_int)]
|
||
|
|
||
|
def __del__(self):
|
||
|
_CXString_dispose(self)
|
||
|
|
||
|
@staticmethod
|
||
|
def from_result(res, fn, args):
|
||
|
assert isinstance(res, _CXString)
|
||
|
return _CXString_getCString(res)
|
||
|
|
||
|
class SourceLocation(Structure):
|
||
|
"""
|
||
|
A SourceLocation represents a particular location within a source file.
|
||
|
"""
|
||
|
_fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
|
||
|
_data = None
|
||
|
|
||
|
def _get_instantiation(self):
|
||
|
if self._data is None:
|
||
|
f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
|
||
|
SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
|
||
|
if f:
|
||
|
f = File(f)
|
||
|
else:
|
||
|
f = None
|
||
|
self._data = (f, int(l.value), int(c.value), int(o.value))
|
||
|
return self._data
|
||
|
|
||
|
@staticmethod
|
||
|
def from_position(tu, file, line, column):
|
||
|
"""
|
||
|
Retrieve the source location associated with a given file/line/column in
|
||
|
a particular translation unit.
|
||
|
"""
|
||
|
return SourceLocation_getLocation(tu, file, line, column)
|
||
|
|
||
|
@property
|
||
|
def file(self):
|
||
|
"""Get the file represented by this source location."""
|
||
|
return self._get_instantiation()[0]
|
||
|
|
||
|
@property
|
||
|
def line(self):
|
||
|
"""Get the line represented by this source location."""
|
||
|
return self._get_instantiation()[1]
|
||
|
|
||
|
@property
|
||
|
def column(self):
|
||
|
"""Get the column represented by this source location."""
|
||
|
return self._get_instantiation()[2]
|
||
|
|
||
|
@property
|
||
|
def offset(self):
|
||
|
"""Get the file offset represented by this source location."""
|
||
|
return self._get_instantiation()[3]
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
return SourceLocation_equalLocations(self, other)
|
||
|
|
||
|
def __ne__(self, other):
|
||
|
return not self.__eq__(other)
|
||
|
|
||
|
def __repr__(self):
|
||
|
if self.file:
|
||
|
filename = self.file.name
|
||
|
else:
|
||
|
filename = None
|
||
|
return "<SourceLocation file %r, line %r, column %r>" % (
|
||
|
filename, self.line, self.column)
|
||
|
|
||
|
class SourceRange(Structure):
|
||
|
"""
|
||
|
A SourceRange describes a range of source locations within the source
|
||
|
code.
|
||
|
"""
|
||
|
_fields_ = [
|
||
|
("ptr_data", c_void_p * 2),
|
||
|
("begin_int_data", c_uint),
|
||
|
("end_int_data", c_uint)]
|
||
|
|
||
|
# FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
|
||
|
# object.
|
||
|
@staticmethod
|
||
|
def from_locations(start, end):
|
||
|
return SourceRange_getRange(start, end)
|
||
|
|
||
|
@property
|
||
|
def start(self):
|
||
|
"""
|
||
|
Return a SourceLocation representing the first character within a
|
||
|
source range.
|
||
|
"""
|
||
|
return SourceRange_start(self)
|
||
|
|
||
|
@property
|
||
|
def end(self):
|
||
|
"""
|
||
|
Return a SourceLocation representing the last character within a
|
||
|
source range.
|
||
|
"""
|
||
|
return SourceRange_end(self)
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
return SourceRange_equalRanges(self, other)
|
||
|
|
||
|
def __ne__(self, other):
|
||
|
return not self.__eq__(other)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<SourceRange start %r, end %r>" % (self.start, self.end)
|
||
|
|
||
|
class Diagnostic(object):
|
||
|
"""
|
||
|
A Diagnostic is a single instance of a Clang diagnostic. It includes the
|
||
|
diagnostic severity, the message, the location the diagnostic occurred, as
|
||
|
well as additional source ranges and associated fix-it hints.
|
||
|
"""
|
||
|
|
||
|
Ignored = 0
|
||
|
Note = 1
|
||
|
Warning = 2
|
||
|
Error = 3
|
||
|
Fatal = 4
|
||
|
|
||
|
def __init__(self, ptr):
|
||
|
self.ptr = ptr
|
||
|
|
||
|
def __del__(self):
|
||
|
_clang_disposeDiagnostic(self)
|
||
|
|
||
|
@property
|
||
|
def severity(self):
|
||
|
return _clang_getDiagnosticSeverity(self)
|
||
|
|
||
|
@property
|
||
|
def location(self):
|
||
|
return _clang_getDiagnosticLocation(self)
|
||
|
|
||
|
@property
|
||
|
def spelling(self):
|
||
|
return _clang_getDiagnosticSpelling(self)
|
||
|
|
||
|
@property
|
||
|
def ranges(self):
|
||
|
class RangeIterator:
|
||
|
def __init__(self, diag):
|
||
|
self.diag = diag
|
||
|
|
||
|
def __len__(self):
|
||
|
return int(_clang_getDiagnosticNumRanges(self.diag))
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
if (key >= len(self)):
|
||
|
raise IndexError
|
||
|
return _clang_getDiagnosticRange(self.diag, key)
|
||
|
|
||
|
return RangeIterator(self)
|
||
|
|
||
|
@property
|
||
|
def fixits(self):
|
||
|
class FixItIterator:
|
||
|
def __init__(self, diag):
|
||
|
self.diag = diag
|
||
|
|
||
|
def __len__(self):
|
||
|
return int(_clang_getDiagnosticNumFixIts(self.diag))
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
range = SourceRange()
|
||
|
value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
|
||
|
if len(value) == 0:
|
||
|
raise IndexError
|
||
|
|
||
|
return FixIt(range, value)
|
||
|
|
||
|
return FixItIterator(self)
|
||
|
|
||
|
@property
|
||
|
def category_number(self):
|
||
|
"""The category number for this diagnostic."""
|
||
|
return _clang_getDiagnosticCategory(self)
|
||
|
|
||
|
@property
|
||
|
def category_name(self):
|
||
|
"""The string name of the category for this diagnostic."""
|
||
|
return _clang_getDiagnosticCategoryName(self.category_number)
|
||
|
|
||
|
@property
|
||
|
def option(self):
|
||
|
"""The command-line option that enables this diagnostic."""
|
||
|
return _clang_getDiagnosticOption(self, None)
|
||
|
|
||
|
@property
|
||
|
def disable_option(self):
|
||
|
"""The command-line option that disables this diagnostic."""
|
||
|
disable = _CXString()
|
||
|
_clang_getDiagnosticOption(self, byref(disable))
|
||
|
|
||
|
return _CXString_getCString(disable)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<Diagnostic severity %r, location %r, spelling %r>" % (
|
||
|
self.severity, self.location, self.spelling)
|
||
|
|
||
|
def from_param(self):
|
||
|
return self.ptr
|
||
|
|
||
|
class FixIt(object):
|
||
|
"""
|
||
|
A FixIt represents a transformation to be applied to the source to
|
||
|
"fix-it". The fix-it shouldbe applied by replacing the given source range
|
||
|
with the given value.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, range, value):
|
||
|
self.range = range
|
||
|
self.value = value
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<FixIt range %r, value %r>" % (self.range, self.value)
|
||
|
|
||
|
### Access Specifier Kinds ###
|
||
|
|
||
|
class AccessSpecifierKind(object):
|
||
|
"""
|
||
|
An AccessSpecifierKind describes the kind of access specifier a cursor
|
||
|
points to.
|
||
|
"""
|
||
|
|
||
|
_kinds = []
|
||
|
_name_map = None
|
||
|
|
||
|
def __init__(self, value):
|
||
|
if value >= len(AccessSpecifierKind._kinds):
|
||
|
AccessSpecifierKind._kinds += [None] * (value - len(AccessSpecifierKind._kinds) + 1)
|
||
|
if AccessSpecifierKind._kinds[value] is not None:
|
||
|
raise ValueError,'AccessSpecifierKind already loaded'
|
||
|
self.value = value
|
||
|
AccessSpecifierKind._kinds[value] = self
|
||
|
AccessSpecifierKind._name_map = None
|
||
|
|
||
|
def from_param(self):
|
||
|
return self.value
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
"""Get the enumeration name of this access specifier kind"""
|
||
|
if self._name_map is None:
|
||
|
self._name_map = {}
|
||
|
for key,value in AccessSpecifierKind.__dict__.items():
|
||
|
if isinstance(value,AccessSpecifierKind):
|
||
|
self._name_map[value] = key
|
||
|
return self._name_map[self]
|
||
|
|
||
|
@staticmethod
|
||
|
def from_id(id):
|
||
|
if id >= len(AccessSpecifierKind._kinds) or AccessSpecifierKind._kinds[id] is None:
|
||
|
raise ValueError,'Unknown access specifier kind'
|
||
|
return AccessSpecifierKind._kinds[id]
|
||
|
|
||
|
@staticmethod
|
||
|
def get_all_kinds():
|
||
|
"""Return all AccessSpecifierKind enumeration instances."""
|
||
|
return filter(None, AccessSpecifierKind._kinds)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return 'AccessSpecifierKind.%s' % (self.name,)
|
||
|
|
||
|
###
|
||
|
# Declaration Kinds
|
||
|
|
||
|
AccessSpecifierKind.INVALID = AccessSpecifierKind(0)
|
||
|
AccessSpecifierKind.PUBLIC = AccessSpecifierKind(1)
|
||
|
AccessSpecifierKind.PROTECTED = AccessSpecifierKind(2)
|
||
|
AccessSpecifierKind.PRIVATE = AccessSpecifierKind(3)
|
||
|
|
||
|
|
||
|
### Cursor Kinds ###
|
||
|
|
||
|
class CursorKind(object):
|
||
|
"""
|
||
|
A CursorKind describes the kind of entity that a cursor points to.
|
||
|
"""
|
||
|
|
||
|
# The unique kind objects, indexed by id.
|
||
|
_kinds = []
|
||
|
_name_map = None
|
||
|
|
||
|
def __init__(self, value):
|
||
|
if value >= len(CursorKind._kinds):
|
||
|
CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
|
||
|
if CursorKind._kinds[value] is not None:
|
||
|
raise ValueError,'CursorKind already loaded'
|
||
|
self.value = value
|
||
|
CursorKind._kinds[value] = self
|
||
|
CursorKind._name_map = None
|
||
|
|
||
|
def from_param(self):
|
||
|
return self.value
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
"""Get the enumeration name of this cursor kind."""
|
||
|
if self._name_map is None:
|
||
|
self._name_map = {}
|
||
|
for key,value in CursorKind.__dict__.items():
|
||
|
if isinstance(value,CursorKind):
|
||
|
self._name_map[value] = key
|
||
|
return self._name_map[self]
|
||
|
|
||
|
@staticmethod
|
||
|
def from_id(id):
|
||
|
if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
|
||
|
raise ValueError,'Unknown cursor kind'
|
||
|
return CursorKind._kinds[id]
|
||
|
|
||
|
@staticmethod
|
||
|
def get_all_kinds():
|
||
|
"""Return all CursorKind enumeration instances."""
|
||
|
return filter(None, CursorKind._kinds)
|
||
|
|
||
|
def is_declaration(self):
|
||
|
"""Test if this is a declaration kind."""
|
||
|
return CursorKind_is_decl(self)
|
||
|
|
||
|
def is_reference(self):
|
||
|
"""Test if this is a reference kind."""
|
||
|
return CursorKind_is_ref(self)
|
||
|
|
||
|
def is_expression(self):
|
||
|
"""Test if this is an expression kind."""
|
||
|
return CursorKind_is_expr(self)
|
||
|
|
||
|
def is_statement(self):
|
||
|
"""Test if this is a statement kind."""
|
||
|
return CursorKind_is_stmt(self)
|
||
|
|
||
|
def is_attribute(self):
|
||
|
"""Test if this is an attribute kind."""
|
||
|
return CursorKind_is_attribute(self)
|
||
|
|
||
|
def is_invalid(self):
|
||
|
"""Test if this is an invalid kind."""
|
||
|
return CursorKind_is_inv(self)
|
||
|
|
||
|
def is_translation_unit(self):
|
||
|
"""Test if this is a translation unit kind."""
|
||
|
return CursorKind_is_translation_unit(self)
|
||
|
|
||
|
def is_preprocessing(self):
|
||
|
"""Test if this is a preprocessing kind."""
|
||
|
return CursorKind_is_preprocessing(self)
|
||
|
|
||
|
def is_unexposed(self):
|
||
|
"""Test if this is an unexposed kind."""
|
||
|
return CursorKind_is_unexposed(self)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return 'CursorKind.%s' % (self.name,)
|
||
|
|
||
|
# FIXME: Is there a nicer way to expose this enumeration? We could potentially
|
||
|
# represent the nested structure, or even build a class hierarchy. The main
|
||
|
# things we want for sure are (a) simple external access to kinds, (b) a place
|
||
|
# to hang a description and name, (c) easy to keep in sync with Index.h.
|
||
|
|
||
|
###
|
||
|
# Declaration Kinds
|
||
|
|
||
|
# A declaration whose specific kind is not exposed via this interface.
|
||
|
#
|
||
|
# Unexposed declarations have the same operations as any other kind of
|
||
|
# declaration; one can extract their location information, spelling, find their
|
||
|
# definitions, etc. However, the specific kind of the declaration is not
|
||
|
# reported.
|
||
|
CursorKind.UNEXPOSED_DECL = CursorKind(1)
|
||
|
|
||
|
# A C or C++ struct.
|
||
|
CursorKind.STRUCT_DECL = CursorKind(2)
|
||
|
|
||
|
# A C or C++ union.
|
||
|
CursorKind.UNION_DECL = CursorKind(3)
|
||
|
|
||
|
# A C++ class.
|
||
|
CursorKind.CLASS_DECL = CursorKind(4)
|
||
|
|
||
|
# An enumeration.
|
||
|
CursorKind.ENUM_DECL = CursorKind(5)
|
||
|
|
||
|
# A field (in C) or non-static data member (in C++) in a struct, union, or C++
|
||
|
# class.
|
||
|
CursorKind.FIELD_DECL = CursorKind(6)
|
||
|
|
||
|
# An enumerator constant.
|
||
|
CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
|
||
|
|
||
|
# A function.
|
||
|
CursorKind.FUNCTION_DECL = CursorKind(8)
|
||
|
|
||
|
# A variable.
|
||
|
CursorKind.VAR_DECL = CursorKind(9)
|
||
|
|
||
|
# A function or method parameter.
|
||
|
CursorKind.PARM_DECL = CursorKind(10)
|
||
|
|
||
|
# An Objective-C @interface.
|
||
|
CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
|
||
|
|
||
|
# An Objective-C @interface for a category.
|
||
|
CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
|
||
|
|
||
|
# An Objective-C @protocol declaration.
|
||
|
CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
|
||
|
|
||
|
# An Objective-C @property declaration.
|
||
|
CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
|
||
|
|
||
|
# An Objective-C instance variable.
|
||
|
CursorKind.OBJC_IVAR_DECL = CursorKind(15)
|
||
|
|
||
|
# An Objective-C instance method.
|
||
|
CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
|
||
|
|
||
|
# An Objective-C class method.
|
||
|
CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
|
||
|
|
||
|
# An Objective-C @implementation.
|
||
|
CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
|
||
|
|
||
|
# An Objective-C @implementation for a category.
|
||
|
CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
|
||
|
|
||
|
# A typedef.
|
||
|
CursorKind.TYPEDEF_DECL = CursorKind(20)
|
||
|
|
||
|
# A C++ class method.
|
||
|
CursorKind.CXX_METHOD = CursorKind(21)
|
||
|
|
||
|
# A C++ namespace.
|
||
|
CursorKind.NAMESPACE = CursorKind(22)
|
||
|
|
||
|
# A linkage specification, e.g. 'extern "C"'.
|
||
|
CursorKind.LINKAGE_SPEC = CursorKind(23)
|
||
|
|
||
|
# A C++ constructor.
|
||
|
CursorKind.CONSTRUCTOR = CursorKind(24)
|
||
|
|
||
|
# A C++ destructor.
|
||
|
CursorKind.DESTRUCTOR = CursorKind(25)
|
||
|
|
||
|
# A C++ conversion function.
|
||
|
CursorKind.CONVERSION_FUNCTION = CursorKind(26)
|
||
|
|
||
|
# A C++ template type parameter
|
||
|
CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
|
||
|
|
||
|
# A C++ non-type template paramater.
|
||
|
CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
|
||
|
|
||
|
# A C++ template template parameter.
|
||
|
CursorKind.TEMPLATE_TEMPLATE_PARAMTER = CursorKind(29)
|
||
|
|
||
|
# A C++ function template.
|
||
|
CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
|
||
|
|
||
|
# A C++ class template.
|
||
|
CursorKind.CLASS_TEMPLATE = CursorKind(31)
|
||
|
|
||
|
# A C++ class template partial specialization.
|
||
|
CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
|
||
|
|
||
|
# A C++ namespace alias declaration.
|
||
|
CursorKind.NAMESPACE_ALIAS = CursorKind(33)
|
||
|
|
||
|
# A C++ using directive
|
||
|
CursorKind.USING_DIRECTIVE = CursorKind(34)
|
||
|
|
||
|
# A C++ using declaration
|
||
|
CursorKind.USING_DECLARATION = CursorKind(35)
|
||
|
|
||
|
# A Type alias decl.
|
||
|
CursorKind.TYPE_ALIAS_DECL = CursorKind(36)
|
||
|
|
||
|
# A Objective-C synthesize decl
|
||
|
CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37)
|
||
|
|
||
|
# A Objective-C dynamic decl
|
||
|
CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38)
|
||
|
|
||
|
# A C++ access specifier decl.
|
||
|
CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39)
|
||
|
|
||
|
|
||
|
###
|
||
|
# Reference Kinds
|
||
|
|
||
|
CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
|
||
|
CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
|
||
|
CursorKind.OBJC_CLASS_REF = CursorKind(42)
|
||
|
|
||
|
# A reference to a type declaration.
|
||
|
#
|
||
|
# A type reference occurs anywhere where a type is named but not
|
||
|
# declared. For example, given:
|
||
|
# typedef unsigned size_type;
|
||
|
# size_type size;
|
||
|
#
|
||
|
# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
|
||
|
# while the type of the variable "size" is referenced. The cursor
|
||
|
# referenced by the type of size is the typedef for size_type.
|
||
|
CursorKind.TYPE_REF = CursorKind(43)
|
||
|
CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
|
||
|
|
||
|
# A reference to a class template, function template, template
|
||
|
# template parameter, or class template partial specialization.
|
||
|
CursorKind.TEMPLATE_REF = CursorKind(45)
|
||
|
|
||
|
# A reference to a namespace or namepsace alias.
|
||
|
CursorKind.NAMESPACE_REF = CursorKind(46)
|
||
|
|
||
|
# A reference to a member of a struct, union, or class that occurs in
|
||
|
# some non-expression context, e.g., a designated initializer.
|
||
|
CursorKind.MEMBER_REF = CursorKind(47)
|
||
|
|
||
|
# A reference to a labeled statement.
|
||
|
CursorKind.LABEL_REF = CursorKind(48)
|
||
|
|
||
|
# A reference toa a set of overloaded functions or function templates
|
||
|
# that has not yet been resolved to a specific function or function template.
|
||
|
CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
|
||
|
|
||
|
###
|
||
|
# Invalid/Error Kinds
|
||
|
|
||
|
CursorKind.INVALID_FILE = CursorKind(70)
|
||
|
CursorKind.NO_DECL_FOUND = CursorKind(71)
|
||
|
CursorKind.NOT_IMPLEMENTED = CursorKind(72)
|
||
|
CursorKind.INVALID_CODE = CursorKind(73)
|
||
|
|
||
|
###
|
||
|
# Expression Kinds
|
||
|
|
||
|
# An expression whose specific kind is not exposed via this interface.
|
||
|
#
|
||
|
# Unexposed expressions have the same operations as any other kind of
|
||
|
# expression; one can extract their location information, spelling, children,
|
||
|
# etc. However, the specific kind of the expression is not reported.
|
||
|
CursorKind.UNEXPOSED_EXPR = CursorKind(100)
|
||
|
|
||
|
# An expression that refers to some value declaration, such as a function,
|
||
|
# varible, or enumerator.
|
||
|
CursorKind.DECL_REF_EXPR = CursorKind(101)
|
||
|
|
||
|
# An expression that refers to a member of a struct, union, class, Objective-C
|
||
|
# class, etc.
|
||
|
CursorKind.MEMBER_REF_EXPR = CursorKind(102)
|
||
|
|
||
|
# An expression that calls a function.
|
||
|
CursorKind.CALL_EXPR = CursorKind(103)
|
||
|
|
||
|
# An expression that sends a message to an Objective-C object or class.
|
||
|
CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
|
||
|
|
||
|
# An expression that represents a block literal.
|
||
|
CursorKind.BLOCK_EXPR = CursorKind(105)
|
||
|
|
||
|
# An integer literal.
|
||
|
CursorKind.INTEGER_LITERAL = CursorKind(106)
|
||
|
|
||
|
# A floating point number literal.
|
||
|
CursorKind.FLOATING_LITERAL = CursorKind(107)
|
||
|
|
||
|
# An imaginary number literal.
|
||
|
CursorKind.IMAGINARY_LITERAL = CursorKind(108)
|
||
|
|
||
|
# A string literal.
|
||
|
CursorKind.STRING_LITERAL = CursorKind(109)
|
||
|
|
||
|
# A character literal.
|
||
|
CursorKind.CHARACTER_LITERAL = CursorKind(110)
|
||
|
|
||
|
# A parenthesized expression, e.g. "(1)".
|
||
|
#
|
||
|
# This AST node is only formed if full location information is requested.
|
||
|
CursorKind.PAREN_EXPR = CursorKind(111)
|
||
|
|
||
|
# This represents the unary-expression's (except sizeof and
|
||
|
# alignof).
|
||
|
CursorKind.UNARY_OPERATOR = CursorKind(112)
|
||
|
|
||
|
# [C99 6.5.2.1] Array Subscripting.
|
||
|
CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113)
|
||
|
|
||
|
# A builtin binary operation expression such as "x + y" or
|
||
|
# "x <= y".
|
||
|
CursorKind.BINARY_OPERATOR = CursorKind(114)
|
||
|
|
||
|
# Compound assignment such as "+=".
|
||
|
CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
|
||
|
|
||
|
# The ?: ternary operator.
|
||
|
CursorKind.CONDITONAL_OPERATOR = CursorKind(116)
|
||
|
|
||
|
# 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.
|
||
|
#
|
||
|
# For example: (int)f.
|
||
|
CursorKind.CSTYLE_CAST_EXPR = CursorKind(117)
|
||
|
|
||
|
# [C99 6.5.2.5]
|
||
|
CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118)
|
||
|
|
||
|
# Describes an C or C++ initializer list.
|
||
|
CursorKind.INIT_LIST_EXPR = CursorKind(119)
|
||
|
|
||
|
# The GNU address of label extension, representing &&label.
|
||
|
CursorKind.ADDR_LABEL_EXPR = CursorKind(120)
|
||
|
|
||
|
# This is the GNU Statement Expression extension: ({int X=4; X;})
|
||
|
CursorKind.StmtExpr = CursorKind(121)
|
||
|
|
||
|
# Represents a C11 generic selection.
|
||
|
CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122)
|
||
|
|
||
|
# Implements the GNU __null extension, which is a name for a null
|
||
|
# pointer constant that has integral type (e.g., int or long) and is the same
|
||
|
# size and alignment as a pointer.
|
||
|
#
|
||
|
# The __null extension is typically only used by system headers, which define
|
||
|
# NULL as __null in C++ rather than using 0 (which is an integer that may not
|
||
|
# match the size of a pointer).
|
||
|
CursorKind.GNU_NULL_EXPR = CursorKind(123)
|
||
|
|
||
|
# C++'s static_cast<> expression.
|
||
|
CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124)
|
||
|
|
||
|
# C++'s dynamic_cast<> expression.
|
||
|
CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125)
|
||
|
|
||
|
# C++'s reinterpret_cast<> expression.
|
||
|
CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126)
|
||
|
|
||
|
# C++'s const_cast<> expression.
|
||
|
CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127)
|
||
|
|
||
|
# Represents an explicit C++ type conversion that uses "functional"
|
||
|
# notion (C++ [expr.type.conv]).
|
||
|
#
|
||
|
# Example:
|
||
|
# \code
|
||
|
# x = int(0.5);
|
||
|
# \endcode
|
||
|
CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128)
|
||
|
|
||
|
# A C++ typeid expression (C++ [expr.typeid]).
|
||
|
CursorKind.CXX_TYPEID_EXPR = CursorKind(129)
|
||
|
|
||
|
# [C++ 2.13.5] C++ Boolean Literal.
|
||
|
CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130)
|
||
|
|
||
|
# [C++0x 2.14.7] C++ Pointer Literal.
|
||
|
CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131)
|
||
|
|
||
|
# Represents the "this" expression in C++
|
||
|
CursorKind.CXX_THIS_EXPR = CursorKind(132)
|
||
|
|
||
|
# [C++ 15] C++ Throw Expression.
|
||
|
#
|
||
|
# This handles 'throw' and 'throw' assignment-expression. When
|
||
|
# assignment-expression isn't present, Op will be null.
|
||
|
CursorKind.CXX_THROW_EXPR = CursorKind(133)
|
||
|
|
||
|
# A new expression for memory allocation and constructor calls, e.g:
|
||
|
# "new CXXNewExpr(foo)".
|
||
|
CursorKind.CXX_NEW_EXPR = CursorKind(134)
|
||
|
|
||
|
# A delete expression for memory deallocation and destructor calls,
|
||
|
# e.g. "delete[] pArray".
|
||
|
CursorKind.CXX_DELETE_EXPR = CursorKind(135)
|
||
|
|
||
|
# Represents a unary expression.
|
||
|
CursorKind.CXX_UNARY_EXPR = CursorKind(136)
|
||
|
|
||
|
# ObjCStringLiteral, used for Objective-C string literals i.e. "foo".
|
||
|
CursorKind.OBJC_STRING_LITERAL = CursorKind(137)
|
||
|
|
||
|
# ObjCEncodeExpr, used for in Objective-C.
|
||
|
CursorKind.OBJC_ENCODE_EXPR = CursorKind(138)
|
||
|
|
||
|
# ObjCSelectorExpr used for in Objective-C.
|
||
|
CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139)
|
||
|
|
||
|
# Objective-C's protocol expression.
|
||
|
CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140)
|
||
|
|
||
|
# An Objective-C "bridged" cast expression, which casts between
|
||
|
# Objective-C pointers and C pointers, transferring ownership in the process.
|
||
|
#
|
||
|
# \code
|
||
|
# NSString *str = (__bridge_transfer NSString *)CFCreateString();
|
||
|
# \endcode
|
||
|
CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141)
|
||
|
|
||
|
# Represents a C++0x pack expansion that produces a sequence of
|
||
|
# expressions.
|
||
|
#
|
||
|
# A pack expansion expression contains a pattern (which itself is an
|
||
|
# expression) followed by an ellipsis. For example:
|
||
|
CursorKind.PACK_EXPANSION_EXPR = CursorKind(142)
|
||
|
|
||
|
# Represents an expression that computes the length of a parameter
|
||
|
# pack.
|
||
|
CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
|
||
|
|
||
|
# A statement whose specific kind is not exposed via this interface.
|
||
|
#
|
||
|
# Unexposed statements have the same operations as any other kind of statement;
|
||
|
# one can extract their location information, spelling, children, etc. However,
|
||
|
# the specific kind of the statement is not reported.
|
||
|
CursorKind.UNEXPOSED_STMT = CursorKind(200)
|
||
|
|
||
|
# A labelled statement in a function.
|
||
|
CursorKind.LABEL_STMT = CursorKind(201)
|
||
|
|
||
|
# A compound statement
|
||
|
CursorKind.COMPOUND_STMT = CursorKind(202)
|
||
|
|
||
|
# A case statement.
|
||
|
CursorKind.CASE_STMT = CursorKind(203)
|
||
|
|
||
|
# A default statement.
|
||
|
CursorKind.DEFAULT_STMT = CursorKind(204)
|
||
|
|
||
|
# An if statement.
|
||
|
CursorKind.IF_STMT = CursorKind(205)
|
||
|
|
||
|
# A switch statement.
|
||
|
CursorKind.SWITCH_STMT = CursorKind(206)
|
||
|
|
||
|
# A while statement.
|
||
|
CursorKind.WHILE_STMT = CursorKind(207)
|
||
|
|
||
|
# A do statement.
|
||
|
CursorKind.DO_STMT = CursorKind(208)
|
||
|
|
||
|
# A for statement.
|
||
|
CursorKind.FOR_STMT = CursorKind(209)
|
||
|
|
||
|
# A goto statement.
|
||
|
CursorKind.GOTO_STMT = CursorKind(210)
|
||
|
|
||
|
# An indirect goto statement.
|
||
|
CursorKind.INDIRECT_GOTO_STMT = CursorKind(211)
|
||
|
|
||
|
# A continue statement.
|
||
|
CursorKind.CONTINUE_STMT = CursorKind(212)
|
||
|
|
||
|
# A break statement.
|
||
|
CursorKind.BREAK_STMT = CursorKind(213)
|
||
|
|
||
|
# A return statement.
|
||
|
CursorKind.RETURN_STMT = CursorKind(214)
|
||
|
|
||
|
# A GNU-style inline assembler statement.
|
||
|
CursorKind.ASM_STMT = CursorKind(215)
|
||
|
|
||
|
# Objective-C's overall @try-@catch-@finally statement.
|
||
|
CursorKind.OBJC_AT_TRY_STMT = CursorKind(216)
|
||
|
|
||
|
# Objective-C's @catch statement.
|
||
|
CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217)
|
||
|
|
||
|
# Objective-C's @finally statement.
|
||
|
CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218)
|
||
|
|
||
|
# Objective-C's @throw statement.
|
||
|
CursorKind.OBJC_AT_THROW_STMT = CursorKind(219)
|
||
|
|
||
|
# Objective-C's @synchronized statement.
|
||
|
CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220)
|
||
|
|
||
|
# Objective-C's autorealease pool statement.
|
||
|
CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221)
|
||
|
|
||
|
# Objective-C's for collection statement.
|
||
|
CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222)
|
||
|
|
||
|
# C++'s catch statement.
|
||
|
CursorKind.CXX_CATCH_STMT = CursorKind(223)
|
||
|
|
||
|
# C++'s try statement.
|
||
|
CursorKind.CXX_TRY_STMT = CursorKind(224)
|
||
|
|
||
|
# C++'s for (* : *) statement.
|
||
|
CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225)
|
||
|
|
||
|
# Windows Structured Exception Handling's try statement.
|
||
|
CursorKind.SEH_TRY_STMT = CursorKind(226)
|
||
|
|
||
|
# Windows Structured Exception Handling's except statement.
|
||
|
CursorKind.SEH_EXCEPT_STMT = CursorKind(227)
|
||
|
|
||
|
# Windows Structured Exception Handling's finally statement.
|
||
|
CursorKind.SEH_FINALLY_STMT = CursorKind(228)
|
||
|
|
||
|
# The null statement.
|
||
|
CursorKind.NULL_STMT = CursorKind(230)
|
||
|
|
||
|
# Adaptor class for mixing declarations with statements and expressions.
|
||
|
CursorKind.DECL_STMT = CursorKind(231)
|
||
|
|
||
|
###
|
||
|
# Other Kinds
|
||
|
|
||
|
# Cursor that represents the translation unit itself.
|
||
|
#
|
||
|
# The translation unit cursor exists primarily to act as the root cursor for
|
||
|
# traversing the contents of a translation unit.
|
||
|
CursorKind.TRANSLATION_UNIT = CursorKind(300)
|
||
|
|
||
|
###
|
||
|
# Attributes
|
||
|
|
||
|
# An attribute whoe specific kind is note exposed via this interface
|
||
|
CursorKind.UNEXPOSED_ATTR = CursorKind(400)
|
||
|
|
||
|
CursorKind.IB_ACTION_ATTR = CursorKind(401)
|
||
|
CursorKind.IB_OUTLET_ATTR = CursorKind(402)
|
||
|
CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
|
||
|
|
||
|
CursorKind.CXX_FINAL_ATTR = CursorKind(404)
|
||
|
CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405)
|
||
|
CursorKind.ANNOTATE_ATTR = CursorKind(406)
|
||
|
CursorKind.ASM_LABEL_ATTR = CursorKind(407)
|
||
|
|
||
|
###
|
||
|
# Preprocessing
|
||
|
CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
|
||
|
CursorKind.MACRO_DEFINITION = CursorKind(501)
|
||
|
CursorKind.MACRO_INSTANTIATION = CursorKind(502)
|
||
|
CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
|
||
|
|
||
|
### Cursors ###
|
||
|
|
||
|
class Cursor(Structure):
|
||
|
"""
|
||
|
The Cursor class represents a reference to an element within the AST. It
|
||
|
acts as a kind of iterator.
|
||
|
"""
|
||
|
_fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
|
||
|
|
||
|
@staticmethod
|
||
|
def from_location(tu, location):
|
||
|
# We store a reference to the TU in the instance so the TU won't get
|
||
|
# collected before the cursor.
|
||
|
cursor = Cursor_get(tu, location)
|
||
|
cursor._tu = tu
|
||
|
|
||
|
return cursor
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
return Cursor_eq(self, other)
|
||
|
|
||
|
def __ne__(self, other):
|
||
|
return not self.__eq__(other)
|
||
|
|
||
|
def is_definition(self):
|
||
|
"""
|
||
|
Returns true if the declaration pointed at by the cursor is also a
|
||
|
definition of that entity.
|
||
|
"""
|
||
|
return Cursor_is_def(self)
|
||
|
|
||
|
def get_definition(self):
|
||
|
"""
|
||
|
If the cursor is a reference to a declaration or a declaration of
|
||
|
some entity, return a cursor that points to the definition of that
|
||
|
entity.
|
||
|
"""
|
||
|
# TODO: Should probably check that this is either a reference or
|
||
|
# declaration prior to issuing the lookup.
|
||
|
return Cursor_def(self)
|
||
|
|
||
|
def get_usr(self):
|
||
|
"""Return the Unified Symbol Resultion (USR) for the entity referenced
|
||
|
by the given cursor (or None).
|
||
|
|
||
|
A Unified Symbol Resolution (USR) is a string that identifies a
|
||
|
particular entity (function, class, variable, etc.) within a
|
||
|
program. USRs can be compared across translation units to determine,
|
||
|
e.g., when references in one translation refer to an entity defined in
|
||
|
another translation unit."""
|
||
|
return Cursor_usr(self)
|
||
|
|
||
|
@property
|
||
|
def kind(self):
|
||
|
"""Return the kind of this cursor."""
|
||
|
return CursorKind.from_id(self._kind_id)
|
||
|
|
||
|
@property
|
||
|
def spelling(self):
|
||
|
"""Return the spelling of the entity pointed at by the cursor."""
|
||
|
if not self.kind.is_declaration():
|
||
|
# FIXME: clang_getCursorSpelling should be fixed to not assert on
|
||
|
# this, for consistency with clang_getCursorUSR.
|
||
|
return None
|
||
|
if not hasattr(self, '_spelling'):
|
||
|
self._spelling = Cursor_spelling(self)
|
||
|
return self._spelling
|
||
|
|
||
|
@property
|
||
|
def displayname(self):
|
||
|
"""
|
||
|
Return the display name for the entity referenced by this cursor.
|
||
|
|
||
|
The display name contains extra information that helps identify the cursor,
|
||
|
such as the parameters of a function or template or the arguments of a
|
||
|
class template specialization.
|
||
|
"""
|
||
|
if not hasattr(self, '_displayname'):
|
||
|
self._displayname = Cursor_displayname(self)
|
||
|
return self._displayname
|
||
|
|
||
|
@property
|
||
|
def location(self):
|
||
|
"""
|
||
|
Return the source location (the starting character) of the entity
|
||
|
pointed at by the cursor.
|
||
|
"""
|
||
|
if not hasattr(self, '_loc'):
|
||
|
self._loc = Cursor_loc(self)
|
||
|
return self._loc
|
||
|
|
||
|
@property
|
||
|
def extent(self):
|
||
|
"""
|
||
|
Return the source range (the range of text) occupied by the entity
|
||
|
pointed at by the cursor.
|
||
|
"""
|
||
|
if not hasattr(self, '_extent'):
|
||
|
self._extent = Cursor_extent(self)
|
||
|
return self._extent
|
||
|
|
||
|
@property
|
||
|
def type(self):
|
||
|
"""
|
||
|
Retrieve the Type (if any) of the entity pointed at by the cursor.
|
||
|
"""
|
||
|
if not hasattr(self, '_type'):
|
||
|
self._type = Cursor_type(self)
|
||
|
return self._type
|
||
|
|
||
|
@property
|
||
|
def canonical(self):
|
||
|
"""Return the canonical Cursor corresponding to this Cursor.
|
||
|
|
||
|
The canonical cursor is the cursor which is representative for the
|
||
|
underlying entity. For example, if you have multiple forward
|
||
|
declarations for the same class, the canonical cursor for the forward
|
||
|
declarations will be identical.
|
||
|
"""
|
||
|
if not hasattr(self, '_canonical'):
|
||
|
self._canonical = Cursor_canonical(self)
|
||
|
|
||
|
return self._canonical
|
||
|
|
||
|
@property
|
||
|
def result_type(self):
|
||
|
"""Retrieve the Type of the result for this Cursor."""
|
||
|
if not hasattr(self, '_result_type'):
|
||
|
self._result_type = Type_get_result(self.type)
|
||
|
|
||
|
return self._result_type
|
||
|
|
||
|
@property
|
||
|
def underlying_typedef_type(self):
|
||
|
"""Return the underlying type of a typedef declaration.
|
||
|
|
||
|
Returns a Type for the typedef this cursor is a declaration for. If
|
||
|
the current cursor is not a typedef, this raises.
|
||
|
"""
|
||
|
if not hasattr(self, '_underlying_type'):
|
||
|
assert self.kind.is_declaration()
|
||
|
self._underlying_type = Cursor_underlying_type(self)
|
||
|
|
||
|
return self._underlying_type
|
||
|
|
||
|
@property
|
||
|
def enum_type(self):
|
||
|
"""Return the integer type of an enum declaration.
|
||
|
|
||
|
Returns a Type corresponding to an integer. If the cursor is not for an
|
||
|
enum, this raises.
|
||
|
"""
|
||
|
if not hasattr(self, '_enum_type'):
|
||
|
assert self.kind == CursorKind.ENUM_DECL
|
||
|
self._enum_type = Cursor_enum_type(self)
|
||
|
|
||
|
return self._enum_type
|
||
|
|
||
|
@property
|
||
|
def enum_value(self):
|
||
|
"""Return the value of an enum constant."""
|
||
|
if not hasattr(self, '_enum_value'):
|
||
|
assert self.kind == CursorKind.ENUM_CONSTANT_DECL
|
||
|
# Figure out the underlying type of the enum to know if it
|
||
|
# is a signed or unsigned quantity.
|
||
|
underlying_type = self.type
|
||
|
if underlying_type.kind == TypeKind.ENUM:
|
||
|
underlying_type = underlying_type.get_declaration().enum_type
|
||
|
if underlying_type.kind in (TypeKind.CHAR_U,
|
||
|
TypeKind.UCHAR,
|
||
|
TypeKind.CHAR16,
|
||
|
TypeKind.CHAR32,
|
||
|
TypeKind.USHORT,
|
||
|
TypeKind.UINT,
|
||
|
TypeKind.ULONG,
|
||
|
TypeKind.ULONGLONG,
|
||
|
TypeKind.UINT128):
|
||
|
self._enum_value = Cursor_enum_const_decl_unsigned(self)
|
||
|
else:
|
||
|
self._enum_value = Cursor_enum_const_decl(self)
|
||
|
return self._enum_value
|
||
|
|
||
|
@property
|
||
|
def objc_type_encoding(self):
|
||
|
"""Return the Objective-C type encoding as a str."""
|
||
|
if not hasattr(self, '_objc_type_encoding'):
|
||
|
self._objc_type_encoding = Cursor_objc_type_encoding(self)
|
||
|
|
||
|
return self._objc_type_encoding
|
||
|
|
||
|
@property
|
||
|
def hash(self):
|
||
|
"""Returns a hash of the cursor as an int."""
|
||
|
if not hasattr(self, '_hash'):
|
||
|
self._hash = Cursor_hash(self)
|
||
|
|
||
|
return self._hash
|
||
|
|
||
|
@property
|
||
|
def semantic_parent(self):
|
||
|
"""Return the semantic parent for this cursor."""
|
||
|
if not hasattr(self, '_semantic_parent'):
|
||
|
self._semantic_parent = Cursor_semantic_parent(self)
|
||
|
|
||
|
return self._semantic_parent
|
||
|
|
||
|
@property
|
||
|
def lexical_parent(self):
|
||
|
"""Return the lexical parent for this cursor."""
|
||
|
if not hasattr(self, '_lexical_parent'):
|
||
|
self._lexical_parent = Cursor_lexical_parent(self)
|
||
|
|
||
|
return self._lexical_parent
|
||
|
|
||
|
@property
|
||
|
def translation_unit(self):
|
||
|
"""Returns the TranslationUnit to which this Cursor belongs."""
|
||
|
# If this triggers an AttributeError, the instance was not properly
|
||
|
# created.
|
||
|
return self._tu
|
||
|
|
||
|
def get_children(self):
|
||
|
"""Return an iterator for accessing the children of this cursor."""
|
||
|
|
||
|
# FIXME: Expose iteration from CIndex, PR6125.
|
||
|
def visitor(child, parent, children):
|
||
|
# FIXME: Document this assertion in API.
|
||
|
# FIXME: There should just be an isNull method.
|
||
|
assert child != Cursor_null()
|
||
|
|
||
|
# Create reference to TU so it isn't GC'd before Cursor.
|
||
|
child._tu = self._tu
|
||
|
children.append(child)
|
||
|
return 1 # continue
|
||
|
children = []
|
||
|
Cursor_visit(self, Cursor_visit_callback(visitor), children)
|
||
|
return iter(children)
|
||
|
|
||
|
def get_children_array(self):
|
||
|
"""Return an iterator for accessing the children of this cursor."""
|
||
|
|
||
|
# FIXME: Expose iteration from CIndex, PR6125.
|
||
|
def visitor(child, parent, children):
|
||
|
# FIXME: Document this assertion in API.
|
||
|
# FIXME: There should just be an isNull method.
|
||
|
assert child != Cursor_null()
|
||
|
|
||
|
# Create reference to TU so it isn't GC'd before Cursor.
|
||
|
child._tu = self._tu
|
||
|
children.append(child)
|
||
|
return 1 # continue
|
||
|
children = []
|
||
|
Cursor_visit(self, Cursor_visit_callback(visitor), children)
|
||
|
return children
|
||
|
|
||
|
def is_method_static(self):
|
||
|
assert self.kind == CursorKind.CXX_METHOD
|
||
|
return Cursor_CXXMethod_isStatic(self)
|
||
|
|
||
|
def get_access_specifier(self):
|
||
|
assert self.kind == CursorKind.CXX_ACCESS_SPEC_DECL
|
||
|
return Cursor_getCXXAccessSpecifier(self)
|
||
|
|
||
|
@staticmethod
|
||
|
def from_result(res, fn, args):
|
||
|
assert isinstance(res, Cursor)
|
||
|
# FIXME: There should just be an isNull method.
|
||
|
if res == Cursor_null():
|
||
|
return None
|
||
|
|
||
|
# Store a reference to the TU in the Python object so it won't get GC'd
|
||
|
# before the Cursor.
|
||
|
tu = None
|
||
|
for arg in args:
|
||
|
if isinstance(arg, TranslationUnit):
|
||
|
tu = arg
|
||
|
break
|
||
|
|
||
|
if hasattr(arg, 'translation_unit'):
|
||
|
tu = arg.translation_unit
|
||
|
break
|
||
|
|
||
|
assert tu is not None
|
||
|
|
||
|
res._tu = tu
|
||
|
return res
|
||
|
|
||
|
|
||
|
### Type Kinds ###
|
||
|
|
||
|
class TypeKind(object):
|
||
|
"""
|
||
|
Describes the kind of type.
|
||
|
"""
|
||
|
|
||
|
# The unique kind objects, indexed by id.
|
||
|
_kinds = []
|
||
|
_name_map = None
|
||
|
|
||
|
def __init__(self, value):
|
||
|
if value >= len(TypeKind._kinds):
|
||
|
TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
|
||
|
if TypeKind._kinds[value] is not None:
|
||
|
raise ValueError,'TypeKind already loaded'
|
||
|
self.value = value
|
||
|
TypeKind._kinds[value] = self
|
||
|
TypeKind._name_map = None
|
||
|
|
||
|
def from_param(self):
|
||
|
return self.value
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
"""Get the enumeration name of this cursor kind."""
|
||
|
if self._name_map is None:
|
||
|
self._name_map = {}
|
||
|
for key,value in TypeKind.__dict__.items():
|
||
|
if isinstance(value,TypeKind):
|
||
|
self._name_map[value] = key
|
||
|
return self._name_map[self]
|
||
|
|
||
|
@property
|
||
|
def spelling(self):
|
||
|
"""Retrieve the spelling of this TypeKind."""
|
||
|
return TypeKind_spelling(self.value)
|
||
|
|
||
|
@staticmethod
|
||
|
def from_id(id):
|
||
|
if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
|
||
|
raise ValueError,'Unknown type kind %d' % id
|
||
|
return TypeKind._kinds[id]
|
||
|
|
||
|
def __repr__(self):
|
||
|
return 'TypeKind.%s' % (self.name,)
|
||
|
|
||
|
TypeKind_spelling = lib.clang_getTypeKindSpelling
|
||
|
TypeKind_spelling.argtypes = [c_uint]
|
||
|
TypeKind_spelling.restype = _CXString
|
||
|
TypeKind_spelling.errcheck = _CXString.from_result
|
||
|
|
||
|
|
||
|
TypeKind.INVALID = TypeKind(0)
|
||
|
TypeKind.UNEXPOSED = TypeKind(1)
|
||
|
TypeKind.VOID = TypeKind(2)
|
||
|
TypeKind.BOOL = TypeKind(3)
|
||
|
TypeKind.CHAR_U = TypeKind(4)
|
||
|
TypeKind.UCHAR = TypeKind(5)
|
||
|
TypeKind.CHAR16 = TypeKind(6)
|
||
|
TypeKind.CHAR32 = TypeKind(7)
|
||
|
TypeKind.USHORT = TypeKind(8)
|
||
|
TypeKind.UINT = TypeKind(9)
|
||
|
TypeKind.ULONG = TypeKind(10)
|
||
|
TypeKind.ULONGLONG = TypeKind(11)
|
||
|
TypeKind.UINT128 = TypeKind(12)
|
||
|
TypeKind.CHAR_S = TypeKind(13)
|
||
|
TypeKind.SCHAR = TypeKind(14)
|
||
|
TypeKind.WCHAR = TypeKind(15)
|
||
|
TypeKind.SHORT = TypeKind(16)
|
||
|
TypeKind.INT = TypeKind(17)
|
||
|
TypeKind.LONG = TypeKind(18)
|
||
|
TypeKind.LONGLONG = TypeKind(19)
|
||
|
TypeKind.INT128 = TypeKind(20)
|
||
|
TypeKind.FLOAT = TypeKind(21)
|
||
|
TypeKind.DOUBLE = TypeKind(22)
|
||
|
TypeKind.LONGDOUBLE = TypeKind(23)
|
||
|
TypeKind.NULLPTR = TypeKind(24)
|
||
|
TypeKind.OVERLOAD = TypeKind(25)
|
||
|
TypeKind.DEPENDENT = TypeKind(26)
|
||
|
TypeKind.OBJCID = TypeKind(27)
|
||
|
TypeKind.OBJCCLASS = TypeKind(28)
|
||
|
TypeKind.OBJCSEL = TypeKind(29)
|
||
|
TypeKind.COMPLEX = TypeKind(100)
|
||
|
TypeKind.POINTER = TypeKind(101)
|
||
|
TypeKind.BLOCKPOINTER = TypeKind(102)
|
||
|
TypeKind.LVALUEREFERENCE = TypeKind(103)
|
||
|
TypeKind.RVALUEREFERENCE = TypeKind(104)
|
||
|
TypeKind.RECORD = TypeKind(105)
|
||
|
TypeKind.ENUM = TypeKind(106)
|
||
|
TypeKind.TYPEDEF = TypeKind(107)
|
||
|
TypeKind.OBJCINTERFACE = TypeKind(108)
|
||
|
TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
|
||
|
TypeKind.FUNCTIONNOPROTO = TypeKind(110)
|
||
|
TypeKind.FUNCTIONPROTO = TypeKind(111)
|
||
|
TypeKind.CONSTANTARRAY = TypeKind(112)
|
||
|
TypeKind.VECTOR = TypeKind(113)
|
||
|
|
||
|
class Type(Structure):
|
||
|
"""
|
||
|
The type of an element in the abstract syntax tree.
|
||
|
"""
|
||
|
_fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
|
||
|
|
||
|
@property
|
||
|
def kind(self):
|
||
|
"""Return the kind of this type."""
|
||
|
return TypeKind.from_id(self._kind_id)
|
||
|
|
||
|
def argument_types(self):
|
||
|
"""Retrieve a container for the non-variadic arguments for this type.
|
||
|
|
||
|
The returned object is iterable and indexable. Each item in the
|
||
|
container is a Type instance.
|
||
|
"""
|
||
|
class ArgumentsIterator(collections.Sequence):
|
||
|
def __init__(self, parent):
|
||
|
self.parent = parent
|
||
|
self.length = None
|
||
|
|
||
|
def __len__(self):
|
||
|
if self.length is None:
|
||
|
self.length = Type_get_num_arg_types(self.parent)
|
||
|
|
||
|
return self.length
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
# FIXME Support slice objects.
|
||
|
if not isinstance(key, int):
|
||
|
raise TypeError("Must supply a non-negative int.")
|
||
|
|
||
|
if key < 0:
|
||
|
raise IndexError("Only non-negative indexes are accepted.")
|
||
|
|
||
|
if key >= len(self):
|
||
|
raise IndexError("Index greater than container length: "
|
||
|
"%d > %d" % ( key, len(self) ))
|
||
|
|
||
|
result = Type_get_arg_type(self.parent, key)
|
||
|
if result.kind == TypeKind.INVALID:
|
||
|
raise IndexError("Argument could not be retrieved.")
|
||
|
|
||
|
return result
|
||
|
|
||
|
assert self.kind == TypeKind.FUNCTIONPROTO
|
||
|
return ArgumentsIterator(self)
|
||
|
|
||
|
@property
|
||
|
def element_type(self):
|
||
|
"""Retrieve the Type of elements within this Type.
|
||
|
|
||
|
If accessed on a type that is not an array, complex, or vector type, an
|
||
|
exception will be raised.
|
||
|
"""
|
||
|
result = Type_get_element_type(self)
|
||
|
if result.kind == TypeKind.INVALID:
|
||
|
raise Exception('Element type not available on this type.')
|
||
|
|
||
|
return result
|
||
|
|
||
|
@property
|
||
|
def element_count(self):
|
||
|
"""Retrieve the number of elements in this type.
|
||
|
|
||
|
Returns an int.
|
||
|
|
||
|
If the Type is not an array or vector, this raises.
|
||
|
"""
|
||
|
result = Type_get_num_elements(self)
|
||
|
if result < 0:
|
||
|
raise Exception('Type does not have elements.')
|
||
|
|
||
|
return result
|
||
|
|
||
|
@property
|
||
|
def translation_unit(self):
|
||
|
"""The TranslationUnit to which this Type is associated."""
|
||
|
# If this triggers an AttributeError, the instance was not properly
|
||
|
# instantiated.
|
||
|
return self._tu
|
||
|
|
||
|
@staticmethod
|
||
|
def from_result(res, fn, args):
|
||
|
assert isinstance(res, Type)
|
||
|
|
||
|
tu = None
|
||
|
for arg in args:
|
||
|
if hasattr(arg, 'translation_unit'):
|
||
|
tu = arg.translation_unit
|
||
|
break
|
||
|
|
||
|
assert tu is not None
|
||
|
res._tu = tu
|
||
|
|
||
|
return res
|
||
|
|
||
|
def get_canonical(self):
|
||
|
"""
|
||
|
Return the canonical type for a Type.
|
||
|
|
||
|
Clang's type system explicitly models typedefs and all the
|
||
|
ways a specific type can be represented. The canonical type
|
||
|
is the underlying type with all the "sugar" removed. For
|
||
|
example, if 'T' is a typedef for 'int', the canonical type for
|
||
|
'T' would be 'int'.
|
||
|
"""
|
||
|
return Type_get_canonical(self)
|
||
|
|
||
|
def is_const_qualified(self):
|
||
|
"""Determine whether a Type has the "const" qualifier set.
|
||
|
|
||
|
This does not look through typedefs that may have added "const"
|
||
|
at a different level.
|
||
|
"""
|
||
|
return Type_is_const_qualified(self)
|
||
|
|
||
|
def is_volatile_qualified(self):
|
||
|
"""Determine whether a Type has the "volatile" qualifier set.
|
||
|
|
||
|
This does not look through typedefs that may have added "volatile"
|
||
|
at a different level.
|
||
|
"""
|
||
|
return Type_is_volatile_qualified(self)
|
||
|
|
||
|
def is_restrict_qualified(self):
|
||
|
"""Determine whether a Type has the "restrict" qualifier set.
|
||
|
|
||
|
This does not look through typedefs that may have added "restrict" at
|
||
|
a different level.
|
||
|
"""
|
||
|
return Type_is_restrict_qualified(self)
|
||
|
|
||
|
def is_function_variadic(self):
|
||
|
"""Determine whether this function Type is a variadic function type."""
|
||
|
assert self.kind == TypeKind.FUNCTIONPROTO
|
||
|
|
||
|
return Type_is_variadic(self)
|
||
|
|
||
|
def is_pod(self):
|
||
|
"""Determine whether this Type represents plain old data (POD)."""
|
||
|
return Type_is_pod(self)
|
||
|
|
||
|
def get_pointee(self):
|
||
|
"""
|
||
|
For pointer types, returns the type of the pointee.
|
||
|
"""
|
||
|
return Type_get_pointee(self)
|
||
|
|
||
|
def get_declaration(self):
|
||
|
"""
|
||
|
Return the cursor for the declaration of the given type.
|
||
|
"""
|
||
|
return Type_get_declaration(self)
|
||
|
|
||
|
def get_result(self):
|
||
|
"""
|
||
|
Retrieve the result type associated with a function type.
|
||
|
"""
|
||
|
return Type_get_result(self)
|
||
|
|
||
|
def get_array_element_type(self):
|
||
|
"""
|
||
|
Retrieve the type of the elements of the array type.
|
||
|
"""
|
||
|
return Type_get_array_element(self)
|
||
|
|
||
|
def get_array_size(self):
|
||
|
"""
|
||
|
Retrieve the size of the constant array.
|
||
|
"""
|
||
|
return Type_get_array_size(self)
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
if type(other) != type(self):
|
||
|
return False
|
||
|
|
||
|
return Type_equal(self, other)
|
||
|
|
||
|
def __ne__(self, other):
|
||
|
return not self.__eq__(other)
|
||
|
|
||
|
## CIndex Objects ##
|
||
|
|
||
|
# CIndex objects (derived from ClangObject) are essentially lightweight
|
||
|
# wrappers attached to some underlying object, which is exposed via CIndex as
|
||
|
# a void*.
|
||
|
|
||
|
class ClangObject(object):
|
||
|
"""
|
||
|
A helper for Clang objects. This class helps act as an intermediary for
|
||
|
the ctypes library and the Clang CIndex library.
|
||
|
"""
|
||
|
def __init__(self, obj):
|
||
|
assert isinstance(obj, c_object_p) and obj
|
||
|
self.obj = self._as_parameter_ = obj
|
||
|
|
||
|
def from_param(self):
|
||
|
return self._as_parameter_
|
||
|
|
||
|
|
||
|
class _CXUnsavedFile(Structure):
|
||
|
"""Helper for passing unsaved file arguments."""
|
||
|
_fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
|
||
|
|
||
|
## Diagnostic Conversion ##
|
||
|
|
||
|
_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
|
||
|
_clang_getNumDiagnostics.argtypes = [c_object_p]
|
||
|
_clang_getNumDiagnostics.restype = c_uint
|
||
|
|
||
|
_clang_getDiagnostic = lib.clang_getDiagnostic
|
||
|
_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
|
||
|
_clang_getDiagnostic.restype = c_object_p
|
||
|
|
||
|
_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
|
||
|
_clang_disposeDiagnostic.argtypes = [Diagnostic]
|
||
|
|
||
|
_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
|
||
|
_clang_getDiagnosticSeverity.argtypes = [Diagnostic]
|
||
|
_clang_getDiagnosticSeverity.restype = c_int
|
||
|
|
||
|
_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
|
||
|
_clang_getDiagnosticLocation.argtypes = [Diagnostic]
|
||
|
_clang_getDiagnosticLocation.restype = SourceLocation
|
||
|
|
||
|
_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
|
||
|
_clang_getDiagnosticSpelling.argtypes = [Diagnostic]
|
||
|
_clang_getDiagnosticSpelling.restype = _CXString
|
||
|
_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
|
||
|
|
||
|
_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
|
||
|
_clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
|
||
|
_clang_getDiagnosticNumRanges.restype = c_uint
|
||
|
|
||
|
_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
|
||
|
_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
|
||
|
_clang_getDiagnosticRange.restype = SourceRange
|
||
|
|
||
|
_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
|
||
|
_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
|
||
|
_clang_getDiagnosticNumFixIts.restype = c_uint
|
||
|
|
||
|
_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
|
||
|
_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
|
||
|
_clang_getDiagnosticFixIt.restype = _CXString
|
||
|
_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
|
||
|
|
||
|
_clang_getDiagnosticCategory = lib.clang_getDiagnosticCategory
|
||
|
_clang_getDiagnosticCategory.argtypes = [Diagnostic]
|
||
|
_clang_getDiagnosticCategory.restype = c_uint
|
||
|
|
||
|
_clang_getDiagnosticCategoryName = lib.clang_getDiagnosticCategoryName
|
||
|
_clang_getDiagnosticCategoryName.argtypes = [c_uint]
|
||
|
_clang_getDiagnosticCategoryName.restype = _CXString
|
||
|
_clang_getDiagnosticCategoryName.errcheck = _CXString.from_result
|
||
|
|
||
|
_clang_getDiagnosticOption = lib.clang_getDiagnosticOption
|
||
|
_clang_getDiagnosticOption.argtypes = [Diagnostic, POINTER(_CXString)]
|
||
|
_clang_getDiagnosticOption.restype = _CXString
|
||
|
_clang_getDiagnosticOption.errcheck = _CXString.from_result
|
||
|
|
||
|
###
|
||
|
|
||
|
class CompletionChunk:
|
||
|
class Kind:
|
||
|
def __init__(self, name):
|
||
|
self.name = name
|
||
|
|
||
|
def __str__(self):
|
||
|
return self.name
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<ChunkKind: %s>" % self
|
||
|
|
||
|
def __init__(self, completionString, key):
|
||
|
self.cs = completionString
|
||
|
self.key = key
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "{'" + self.spelling + "', " + str(self.kind) + "}"
|
||
|
|
||
|
@property
|
||
|
def spelling(self):
|
||
|
return _clang_getCompletionChunkText(self.cs, self.key).spelling
|
||
|
|
||
|
@property
|
||
|
def kind(self):
|
||
|
res = _clang_getCompletionChunkKind(self.cs, self.key)
|
||
|
return completionChunkKindMap[res]
|
||
|
|
||
|
@property
|
||
|
def string(self):
|
||
|
res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
|
||
|
|
||
|
if (res):
|
||
|
return CompletionString(res)
|
||
|
else:
|
||
|
None
|
||
|
|
||
|
def isKindOptional(self):
|
||
|
return self.kind == completionChunkKindMap[0]
|
||
|
|
||
|
def isKindTypedText(self):
|
||
|
return self.kind == completionChunkKindMap[1]
|
||
|
|
||
|
def isKindPlaceHolder(self):
|
||
|
return self.kind == completionChunkKindMap[3]
|
||
|
|
||
|
def isKindInformative(self):
|
||
|
return self.kind == completionChunkKindMap[4]
|
||
|
|
||
|
def isKindResultType(self):
|
||
|
return self.kind == completionChunkKindMap[15]
|
||
|
|
||
|
completionChunkKindMap = {
|
||
|
0: CompletionChunk.Kind("Optional"),
|
||
|
1: CompletionChunk.Kind("TypedText"),
|
||
|
2: CompletionChunk.Kind("Text"),
|
||
|
3: CompletionChunk.Kind("Placeholder"),
|
||
|
4: CompletionChunk.Kind("Informative"),
|
||
|
5: CompletionChunk.Kind("CurrentParameter"),
|
||
|
6: CompletionChunk.Kind("LeftParen"),
|
||
|
7: CompletionChunk.Kind("RightParen"),
|
||
|
8: CompletionChunk.Kind("LeftBracket"),
|
||
|
9: CompletionChunk.Kind("RightBracket"),
|
||
|
10: CompletionChunk.Kind("LeftBrace"),
|
||
|
11: CompletionChunk.Kind("RightBrace"),
|
||
|
12: CompletionChunk.Kind("LeftAngle"),
|
||
|
13: CompletionChunk.Kind("RightAngle"),
|
||
|
14: CompletionChunk.Kind("Comma"),
|
||
|
15: CompletionChunk.Kind("ResultType"),
|
||
|
16: CompletionChunk.Kind("Colon"),
|
||
|
17: CompletionChunk.Kind("SemiColon"),
|
||
|
18: CompletionChunk.Kind("Equal"),
|
||
|
19: CompletionChunk.Kind("HorizontalSpace"),
|
||
|
20: CompletionChunk.Kind("VerticalSpace")}
|
||
|
|
||
|
class CompletionString(ClangObject):
|
||
|
class Availability:
|
||
|
def __init__(self, name):
|
||
|
self.name = name
|
||
|
|
||
|
def __str__(self):
|
||
|
return self.name
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<Availability: %s>" % self
|
||
|
|
||
|
def __len__(self):
|
||
|
return _clang_getNumCompletionChunks(self.obj)
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
if len(self) <= key:
|
||
|
raise IndexError
|
||
|
return CompletionChunk(self.obj, key)
|
||
|
|
||
|
@property
|
||
|
def priority(self):
|
||
|
return _clang_getCompletionPriority(self.obj)
|
||
|
|
||
|
@property
|
||
|
def availability(self):
|
||
|
res = _clang_getCompletionAvailability(self.obj)
|
||
|
return availabilityKinds[res]
|
||
|
|
||
|
def __repr__(self):
|
||
|
return " | ".join([str(a) for a in self]) \
|
||
|
+ " || Priority: " + str(self.priority) \
|
||
|
+ " || Availability: " + str(self.availability)
|
||
|
|
||
|
availabilityKinds = {
|
||
|
0: CompletionChunk.Kind("Available"),
|
||
|
1: CompletionChunk.Kind("Deprecated"),
|
||
|
2: CompletionChunk.Kind("NotAvailable")}
|
||
|
|
||
|
class CodeCompletionResult(Structure):
|
||
|
_fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
|
||
|
|
||
|
def __repr__(self):
|
||
|
return str(CompletionString(self.completionString))
|
||
|
|
||
|
@property
|
||
|
def kind(self):
|
||
|
return CursorKind.from_id(self.cursorKind)
|
||
|
|
||
|
@property
|
||
|
def string(self):
|
||
|
return CompletionString(self.completionString)
|
||
|
|
||
|
class CCRStructure(Structure):
|
||
|
_fields_ = [('results', POINTER(CodeCompletionResult)),
|
||
|
('numResults', c_int)]
|
||
|
|
||
|
def __len__(self):
|
||
|
return self.numResults
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
if len(self) <= key:
|
||
|
raise IndexError
|
||
|
|
||
|
return self.results[key]
|
||
|
|
||
|
class CodeCompletionResults(ClangObject):
|
||
|
def __init__(self, ptr):
|
||
|
assert isinstance(ptr, POINTER(CCRStructure)) and ptr
|
||
|
self.ptr = self._as_parameter_ = ptr
|
||
|
|
||
|
def from_param(self):
|
||
|
return self._as_parameter_
|
||
|
|
||
|
def __del__(self):
|
||
|
CodeCompletionResults_dispose(self)
|
||
|
|
||
|
@property
|
||
|
def results(self):
|
||
|
return self.ptr.contents
|
||
|
|
||
|
@property
|
||
|
def diagnostics(self):
|
||
|
class DiagnosticsItr:
|
||
|
def __init__(self, ccr):
|
||
|
self.ccr= ccr
|
||
|
|
||
|
def __len__(self):
|
||
|
return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
return _clang_codeCompleteGetDiagnostic(self.ccr, key)
|
||
|
|
||
|
return DiagnosticsItr(self)
|
||
|
|
||
|
|
||
|
class Index(ClangObject):
|
||
|
"""
|
||
|
The Index type provides the primary interface to the Clang CIndex library,
|
||
|
primarily by providing an interface for reading and parsing translation
|
||
|
units.
|
||
|
"""
|
||
|
|
||
|
@staticmethod
|
||
|
def create(excludeDecls=False):
|
||
|
"""
|
||
|
Create a new Index.
|
||
|
Parameters:
|
||
|
excludeDecls -- Exclude local declarations from translation units.
|
||
|
"""
|
||
|
return Index(Index_create(excludeDecls, 0))
|
||
|
|
||
|
def __del__(self):
|
||
|
Index_dispose(self)
|
||
|
|
||
|
def read(self, path):
|
||
|
"""Load a TranslationUnit from the given AST file."""
|
||
|
return TranslationUnit.from_ast(path, self)
|
||
|
|
||
|
def parse(self, path, args=None, unsaved_files=None, options = 0):
|
||
|
"""Load the translation unit from the given source code file by running
|
||
|
clang and generating the AST before loading. Additional command line
|
||
|
parameters can be passed to clang via the args parameter.
|
||
|
|
||
|
In-memory contents for files can be provided by passing a list of pairs
|
||
|
to as unsaved_files, the first item should be the filenames to be mapped
|
||
|
and the second should be the contents to be substituted for the
|
||
|
file. The contents may be passed as strings or file objects.
|
||
|
|
||
|
If an error was encountered during parsing, a TranslationUnitLoadError
|
||
|
will be raised.
|
||
|
"""
|
||
|
return TranslationUnit.from_source(path, args, unsaved_files, options,
|
||
|
self)
|
||
|
|
||
|
class TranslationUnit(ClangObject):
|
||
|
"""Represents a source code translation unit.
|
||
|
|
||
|
This is one of the main types in the API. Any time you wish to interact
|
||
|
with Clang's representation of a source file, you typically start with a
|
||
|
translation unit.
|
||
|
"""
|
||
|
|
||
|
# Default parsing mode.
|
||
|
PARSE_NONE = 0
|
||
|
|
||
|
# Instruct the parser to create a detailed processing record containing
|
||
|
# metadata not normally retained.
|
||
|
PARSE_DETAILED_PROCESSING_RECORD = 1
|
||
|
|
||
|
# Indicates that the translation unit is incomplete. This is typically used
|
||
|
# when parsing headers.
|
||
|
PARSE_INCOMPLETE = 2
|
||
|
|
||
|
# Instruct the parser to create a pre-compiled preamble for the translation
|
||
|
# unit. This caches the preamble (included files at top of source file).
|
||
|
# This is useful if the translation unit will be reparsed and you don't
|
||
|
# want to incur the overhead of reparsing the preamble.
|
||
|
PARSE_PRECOMPILED_PREAMBLE = 4
|
||
|
|
||
|
# Cache code completion information on parse. This adds time to parsing but
|
||
|
# speeds up code completion.
|
||
|
PARSE_CACHE_COMPLETION_RESULTS = 8
|
||
|
|
||
|
# Flags with values 16 and 32 are deprecated and intentionally omitted.
|
||
|
|
||
|
# Do not parse function bodies. This is useful if you only care about
|
||
|
# searching for declarations/definitions.
|
||
|
PARSE_SKIP_FUNCTION_BODIES = 64
|
||
|
|
||
|
@classmethod
|
||
|
def from_source(cls, filename, args=None, unsaved_files=None, options=0,
|
||
|
index=None):
|
||
|
"""Create a TranslationUnit by parsing source.
|
||
|
|
||
|
This is capable of processing source code both from files on the
|
||
|
filesystem as well as in-memory contents.
|
||
|
|
||
|
Command-line arguments that would be passed to clang are specified as
|
||
|
a list via args. These can be used to specify include paths, warnings,
|
||
|
etc. e.g. ["-Wall", "-I/path/to/include"].
|
||
|
|
||
|
In-memory file content can be provided via unsaved_files. This is an
|
||
|
iterable of 2-tuples. The first element is the str filename. The
|
||
|
second element defines the content. Content can be provided as str
|
||
|
source code or as file objects (anything with a read() method). If
|
||
|
a file object is being used, content will be read until EOF and the
|
||
|
read cursor will not be reset to its original position.
|
||
|
|
||
|
options is a bitwise or of TranslationUnit.PARSE_XXX flags which will
|
||
|
control parsing behavior.
|
||
|
|
||
|
index is an Index instance to utilize. If not provided, a new Index
|
||
|
will be created for this TranslationUnit.
|
||
|
|
||
|
To parse source from the filesystem, the filename of the file to parse
|
||
|
is specified by the filename argument. Or, filename could be None and
|
||
|
the args list would contain the filename(s) to parse.
|
||
|
|
||
|
To parse source from an in-memory buffer, set filename to the virtual
|
||
|
filename you wish to associate with this source (e.g. "test.c"). The
|
||
|
contents of that file are then provided in unsaved_files.
|
||
|
|
||
|
If an error occurs, a TranslationUnitLoadError is raised.
|
||
|
|
||
|
Please note that a TranslationUnit with parser errors may be returned.
|
||
|
It is the caller's responsibility to check tu.diagnostics for errors.
|
||
|
|
||
|
Also note that Clang infers the source language from the extension of
|
||
|
the input filename. If you pass in source code containing a C++ class
|
||
|
declaration with the filename "test.c" parsing will fail.
|
||
|
"""
|
||
|
if args is None:
|
||
|
args = []
|
||
|
|
||
|
if unsaved_files is None:
|
||
|
unsaved_files = []
|
||
|
|
||
|
if index is None:
|
||
|
index = Index.create()
|
||
|
|
||
|
args_array = None
|
||
|
if len(args) > 0:
|
||
|
args_array = (c_char_p * len(args))(* args)
|
||
|
|
||
|
unsaved_array = None
|
||
|
if len(unsaved_files) > 0:
|
||
|
unsaved_array = (_CXUnsavedFile * len(unsaved_files))()
|
||
|
for i, (name, contents) in enumerate(unsaved_files):
|
||
|
if hasattr(contents, "read"):
|
||
|
contents = contents.read()
|
||
|
|
||
|
unsaved_array[i].name = name
|
||
|
unsaved_array[i].contents = contents
|
||
|
unsaved_array[i].length = len(contents)
|
||
|
|
||
|
ptr = TranslationUnit_parse(index, filename, args_array, len(args),
|
||
|
unsaved_array, len(unsaved_files),
|
||
|
options)
|
||
|
|
||
|
if ptr is None:
|
||
|
raise TranslationUnitLoadError("Error parsing translation unit.")
|
||
|
|
||
|
return cls(ptr, index=index)
|
||
|
|
||
|
@classmethod
|
||
|
def from_ast_file(cls, filename, index=None):
|
||
|
"""Create a TranslationUnit instance from a saved AST file.
|
||
|
|
||
|
A previously-saved AST file (provided with -emit-ast or
|
||
|
TranslationUnit.save()) is loaded from the filename specified.
|
||
|
|
||
|
If the file cannot be loaded, a TranslationUnitLoadError will be
|
||
|
raised.
|
||
|
|
||
|
index is optional and is the Index instance to use. If not provided,
|
||
|
a default Index will be created.
|
||
|
"""
|
||
|
if index is None:
|
||
|
index = Index.create()
|
||
|
|
||
|
ptr = TranslationUnit_read(index, filename)
|
||
|
if ptr is None:
|
||
|
raise TranslationUnitLoadError(filename)
|
||
|
|
||
|
return cls(ptr=ptr, index=index)
|
||
|
|
||
|
def __init__(self, ptr, index):
|
||
|
"""Create a TranslationUnit instance.
|
||
|
|
||
|
TranslationUnits should be created using one of the from_* @classmethod
|
||
|
functions above. __init__ is only called internally.
|
||
|
"""
|
||
|
assert isinstance(index, Index)
|
||
|
|
||
|
ClangObject.__init__(self, ptr)
|
||
|
|
||
|
def __del__(self):
|
||
|
TranslationUnit_dispose(self)
|
||
|
|
||
|
@property
|
||
|
def cursor(self):
|
||
|
"""Retrieve the cursor that represents the given translation unit."""
|
||
|
return TranslationUnit_cursor(self)
|
||
|
|
||
|
@property
|
||
|
def spelling(self):
|
||
|
"""Get the original translation unit source file name."""
|
||
|
return TranslationUnit_spelling(self)
|
||
|
|
||
|
def get_includes(self):
|
||
|
"""
|
||
|
Return an iterable sequence of FileInclusion objects that describe the
|
||
|
sequence of inclusions in a translation unit. The first object in
|
||
|
this sequence is always the input file. Note that this method will not
|
||
|
recursively iterate over header files included through precompiled
|
||
|
headers.
|
||
|
"""
|
||
|
def visitor(fobj, lptr, depth, includes):
|
||
|
if depth > 0:
|
||
|
loc = lptr.contents
|
||
|
includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
|
||
|
|
||
|
# Automatically adapt CIndex/ctype pointers to python objects
|
||
|
includes = []
|
||
|
TranslationUnit_includes(self,
|
||
|
TranslationUnit_includes_callback(visitor),
|
||
|
includes)
|
||
|
return iter(includes)
|
||
|
|
||
|
@property
|
||
|
def diagnostics(self):
|
||
|
"""
|
||
|
Return an iterable (and indexable) object containing the diagnostics.
|
||
|
"""
|
||
|
class DiagIterator:
|
||
|
def __init__(self, tu):
|
||
|
self.tu = tu
|
||
|
|
||
|
def __len__(self):
|
||
|
return int(_clang_getNumDiagnostics(self.tu))
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
diag = _clang_getDiagnostic(self.tu, key)
|
||
|
if not diag:
|
||
|
raise IndexError
|
||
|
return Diagnostic(diag)
|
||
|
|
||
|
return DiagIterator(self)
|
||
|
|
||
|
def reparse(self, unsaved_files=None, options=0):
|
||
|
"""
|
||
|
Reparse an already parsed translation unit.
|
||
|
|
||
|
In-memory contents for files can be provided by passing a list of pairs
|
||
|
as unsaved_files, the first items should be the filenames to be mapped
|
||
|
and the second should be the contents to be substituted for the
|
||
|
file. The contents may be passed as strings or file objects.
|
||
|
"""
|
||
|
if unsaved_files is None:
|
||
|
unsaved_files = []
|
||
|
|
||
|
unsaved_files_array = 0
|
||
|
if len(unsaved_files):
|
||
|
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
|
||
|
for i,(name,value) in enumerate(unsaved_files):
|
||
|
if not isinstance(value, str):
|
||
|
# FIXME: It would be great to support an efficient version
|
||
|
# of this, one day.
|
||
|
value = value.read()
|
||
|
print value
|
||
|
if not isinstance(value, str):
|
||
|
raise TypeError,'Unexpected unsaved file contents.'
|
||
|
unsaved_files_array[i].name = name
|
||
|
unsaved_files_array[i].contents = value
|
||
|
unsaved_files_array[i].length = len(value)
|
||
|
ptr = TranslationUnit_reparse(self, len(unsaved_files),
|
||
|
unsaved_files_array,
|
||
|
options)
|
||
|
|
||
|
def save(self, filename):
|
||
|
"""Saves the TranslationUnit to a file.
|
||
|
|
||
|
This is equivalent to passing -emit-ast to the clang frontend. The
|
||
|
saved file can be loaded back into a TranslationUnit. Or, if it
|
||
|
corresponds to a header, it can be used as a pre-compiled header file.
|
||
|
|
||
|
If an error occurs while saving, a TranslationUnitSaveError is raised.
|
||
|
If the error was TranslationUnitSaveError.ERROR_INVALID_TU, this means
|
||
|
the constructed TranslationUnit was not valid at time of save. In this
|
||
|
case, the reason(s) why should be available via
|
||
|
TranslationUnit.diagnostics().
|
||
|
|
||
|
filename -- The path to save the translation unit to.
|
||
|
"""
|
||
|
options = TranslationUnit_defaultSaveOptions(self)
|
||
|
result = int(TranslationUnit_save(self, filename, options))
|
||
|
if result != 0:
|
||
|
raise TranslationUnitSaveError(result,
|
||
|
'Error saving TranslationUnit.')
|
||
|
|
||
|
def codeComplete(self, path, line, column, unsaved_files=None, options=0):
|
||
|
"""
|
||
|
Code complete in this translation unit.
|
||
|
|
||
|
In-memory contents for files can be provided by passing a list of pairs
|
||
|
as unsaved_files, the first items should be the filenames to be mapped
|
||
|
and the second should be the contents to be substituted for the
|
||
|
file. The contents may be passed as strings or file objects.
|
||
|
"""
|
||
|
if unsaved_files is None:
|
||
|
unsaved_files = []
|
||
|
|
||
|
unsaved_files_array = 0
|
||
|
if len(unsaved_files):
|
||
|
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
|
||
|
for i,(name,value) in enumerate(unsaved_files):
|
||
|
if not isinstance(value, str):
|
||
|
# FIXME: It would be great to support an efficient version
|
||
|
# of this, one day.
|
||
|
value = value.read()
|
||
|
print value
|
||
|
if not isinstance(value, str):
|
||
|
raise TypeError,'Unexpected unsaved file contents.'
|
||
|
unsaved_files_array[i].name = name
|
||
|
unsaved_files_array[i].contents = value
|
||
|
unsaved_files_array[i].length = len(value)
|
||
|
ptr = TranslationUnit_codeComplete(self, path,
|
||
|
line, column,
|
||
|
unsaved_files_array,
|
||
|
len(unsaved_files),
|
||
|
options)
|
||
|
if ptr:
|
||
|
return CodeCompletionResults(ptr)
|
||
|
return None
|
||
|
|
||
|
class File(ClangObject):
|
||
|
"""
|
||
|
The File class represents a particular source file that is part of a
|
||
|
translation unit.
|
||
|
"""
|
||
|
|
||
|
@staticmethod
|
||
|
def from_name(translation_unit, file_name):
|
||
|
"""Retrieve a file handle within the given translation unit."""
|
||
|
return File(File_getFile(translation_unit, file_name))
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
"""Return the complete file and path name of the file."""
|
||
|
return _CXString_getCString(File_name(self))
|
||
|
|
||
|
@property
|
||
|
def time(self):
|
||
|
"""Return the last modification time of the file."""
|
||
|
return File_time(self)
|
||
|
|
||
|
def __str__(self):
|
||
|
return self.name
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<File: %s>" % (self.name)
|
||
|
|
||
|
class FileInclusion(object):
|
||
|
"""
|
||
|
The FileInclusion class represents the inclusion of one source file by
|
||
|
another via a '#include' directive or as the input file for the translation
|
||
|
unit. This class provides information about the included file, the including
|
||
|
file, the location of the '#include' directive and the depth of the included
|
||
|
file in the stack. Note that the input file has depth 0.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, src, tgt, loc, depth):
|
||
|
self.source = src
|
||
|
self.include = tgt
|
||
|
self.location = loc
|
||
|
self.depth = depth
|
||
|
|
||
|
@property
|
||
|
def is_input_file(self):
|
||
|
"""True if the included file is the input file."""
|
||
|
return self.depth == 0
|
||
|
|
||
|
# Additional Functions and Types
|
||
|
|
||
|
# String Functions
|
||
|
_CXString_dispose = lib.clang_disposeString
|
||
|
_CXString_dispose.argtypes = [_CXString]
|
||
|
|
||
|
_CXString_getCString = lib.clang_getCString
|
||
|
_CXString_getCString.argtypes = [_CXString]
|
||
|
_CXString_getCString.restype = c_char_p
|
||
|
|
||
|
# Source Location Functions
|
||
|
SourceLocation_loc = lib.clang_getInstantiationLocation
|
||
|
SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
|
||
|
POINTER(c_uint), POINTER(c_uint),
|
||
|
POINTER(c_uint)]
|
||
|
|
||
|
SourceLocation_getLocation = lib.clang_getLocation
|
||
|
SourceLocation_getLocation.argtypes = [TranslationUnit, File, c_uint, c_uint]
|
||
|
SourceLocation_getLocation.restype = SourceLocation
|
||
|
|
||
|
SourceLocation_equalLocations = lib.clang_equalLocations
|
||
|
SourceLocation_equalLocations.argtypes = [SourceLocation, SourceLocation]
|
||
|
SourceLocation_equalLocations.restype = bool
|
||
|
|
||
|
# Source Range Functions
|
||
|
SourceRange_getRange = lib.clang_getRange
|
||
|
SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
|
||
|
SourceRange_getRange.restype = SourceRange
|
||
|
|
||
|
SourceRange_start = lib.clang_getRangeStart
|
||
|
SourceRange_start.argtypes = [SourceRange]
|
||
|
SourceRange_start.restype = SourceLocation
|
||
|
|
||
|
SourceRange_end = lib.clang_getRangeEnd
|
||
|
SourceRange_end.argtypes = [SourceRange]
|
||
|
SourceRange_end.restype = SourceLocation
|
||
|
|
||
|
SourceRange_equalRanges = lib.clang_equalRanges
|
||
|
SourceRange_equalRanges.argtypes = [SourceRange, SourceRange]
|
||
|
SourceRange_equalRanges.restype = bool
|
||
|
|
||
|
# CursorKind Functions
|
||
|
CursorKind_is_decl = lib.clang_isDeclaration
|
||
|
CursorKind_is_decl.argtypes = [CursorKind]
|
||
|
CursorKind_is_decl.restype = bool
|
||
|
|
||
|
CursorKind_is_ref = lib.clang_isReference
|
||
|
CursorKind_is_ref.argtypes = [CursorKind]
|
||
|
CursorKind_is_ref.restype = bool
|
||
|
|
||
|
CursorKind_is_expr = lib.clang_isExpression
|
||
|
CursorKind_is_expr.argtypes = [CursorKind]
|
||
|
CursorKind_is_expr.restype = bool
|
||
|
|
||
|
CursorKind_is_stmt = lib.clang_isStatement
|
||
|
CursorKind_is_stmt.argtypes = [CursorKind]
|
||
|
CursorKind_is_stmt.restype = bool
|
||
|
|
||
|
CursorKind_is_attribute = lib.clang_isAttribute
|
||
|
CursorKind_is_attribute.argtypes = [CursorKind]
|
||
|
CursorKind_is_attribute.restype = bool
|
||
|
|
||
|
CursorKind_is_inv = lib.clang_isInvalid
|
||
|
CursorKind_is_inv.argtypes = [CursorKind]
|
||
|
CursorKind_is_inv.restype = bool
|
||
|
|
||
|
CursorKind_is_translation_unit = lib.clang_isTranslationUnit
|
||
|
CursorKind_is_translation_unit.argtypes = [CursorKind]
|
||
|
CursorKind_is_translation_unit.restype = bool
|
||
|
|
||
|
CursorKind_is_preprocessing = lib.clang_isPreprocessing
|
||
|
CursorKind_is_preprocessing.argtypes = [CursorKind]
|
||
|
CursorKind_is_preprocessing.restype = bool
|
||
|
|
||
|
CursorKind_is_unexposed = lib.clang_isUnexposed
|
||
|
CursorKind_is_unexposed.argtypes = [CursorKind]
|
||
|
CursorKind_is_unexposed.restype = bool
|
||
|
|
||
|
# Cursor Functions
|
||
|
# TODO: Implement this function
|
||
|
Cursor_get = lib.clang_getCursor
|
||
|
Cursor_get.argtypes = [TranslationUnit, SourceLocation]
|
||
|
Cursor_get.restype = Cursor
|
||
|
|
||
|
Cursor_null = lib.clang_getNullCursor
|
||
|
Cursor_null.restype = Cursor
|
||
|
|
||
|
Cursor_usr = lib.clang_getCursorUSR
|
||
|
Cursor_usr.argtypes = [Cursor]
|
||
|
Cursor_usr.restype = _CXString
|
||
|
Cursor_usr.errcheck = _CXString.from_result
|
||
|
|
||
|
Cursor_is_def = lib.clang_isCursorDefinition
|
||
|
Cursor_is_def.argtypes = [Cursor]
|
||
|
Cursor_is_def.restype = bool
|
||
|
|
||
|
Cursor_def = lib.clang_getCursorDefinition
|
||
|
Cursor_def.argtypes = [Cursor]
|
||
|
Cursor_def.restype = Cursor
|
||
|
Cursor_def.errcheck = Cursor.from_result
|
||
|
|
||
|
Cursor_eq = lib.clang_equalCursors
|
||
|
Cursor_eq.argtypes = [Cursor, Cursor]
|
||
|
Cursor_eq.restype = bool
|
||
|
|
||
|
Cursor_hash = lib.clang_hashCursor
|
||
|
Cursor_hash.argtypes = [Cursor]
|
||
|
Cursor_hash.restype = c_uint
|
||
|
|
||
|
Cursor_spelling = lib.clang_getCursorSpelling
|
||
|
Cursor_spelling.argtypes = [Cursor]
|
||
|
Cursor_spelling.restype = _CXString
|
||
|
Cursor_spelling.errcheck = _CXString.from_result
|
||
|
|
||
|
Cursor_displayname = lib.clang_getCursorDisplayName
|
||
|
Cursor_displayname.argtypes = [Cursor]
|
||
|
Cursor_displayname.restype = _CXString
|
||
|
Cursor_displayname.errcheck = _CXString.from_result
|
||
|
|
||
|
Cursor_loc = lib.clang_getCursorLocation
|
||
|
Cursor_loc.argtypes = [Cursor]
|
||
|
Cursor_loc.restype = SourceLocation
|
||
|
|
||
|
Cursor_extent = lib.clang_getCursorExtent
|
||
|
Cursor_extent.argtypes = [Cursor]
|
||
|
Cursor_extent.restype = SourceRange
|
||
|
|
||
|
Cursor_ref = lib.clang_getCursorReferenced
|
||
|
Cursor_ref.argtypes = [Cursor]
|
||
|
Cursor_ref.restype = Cursor
|
||
|
Cursor_ref.errcheck = Cursor.from_result
|
||
|
|
||
|
Cursor_canonical = lib.clang_getCanonicalCursor
|
||
|
Cursor_canonical.argtypes = [Cursor]
|
||
|
Cursor_canonical.restype = Cursor
|
||
|
Cursor_canonical.errcheck = Cursor.from_result
|
||
|
|
||
|
Cursor_type = lib.clang_getCursorType
|
||
|
Cursor_type.argtypes = [Cursor]
|
||
|
Cursor_type.restype = Type
|
||
|
Cursor_type.errcheck = Type.from_result
|
||
|
|
||
|
Cursor_underlying_type = lib.clang_getTypedefDeclUnderlyingType
|
||
|
Cursor_underlying_type.argtypes = [Cursor]
|
||
|
Cursor_underlying_type.restype = Type
|
||
|
Cursor_underlying_type.errcheck = Type.from_result
|
||
|
|
||
|
Cursor_enum_type = lib.clang_getEnumDeclIntegerType
|
||
|
Cursor_enum_type.argtypes = [Cursor]
|
||
|
Cursor_enum_type.restype = Type
|
||
|
Cursor_enum_type.errcheck = Type.from_result
|
||
|
|
||
|
Cursor_enum_const_decl = lib.clang_getEnumConstantDeclValue
|
||
|
Cursor_enum_const_decl.argtypes = [Cursor]
|
||
|
Cursor_enum_const_decl.restype = c_longlong
|
||
|
|
||
|
Cursor_enum_const_decl_unsigned = lib.clang_getEnumConstantDeclUnsignedValue
|
||
|
Cursor_enum_const_decl_unsigned.argtypes = [Cursor]
|
||
|
Cursor_enum_const_decl_unsigned.restype = c_ulonglong
|
||
|
|
||
|
Cursor_objc_type_encoding = lib.clang_getDeclObjCTypeEncoding
|
||
|
Cursor_objc_type_encoding.argtypes = [Cursor]
|
||
|
Cursor_objc_type_encoding.restype = _CXString
|
||
|
Cursor_objc_type_encoding.errcheck = _CXString.from_result
|
||
|
|
||
|
Cursor_semantic_parent = lib.clang_getCursorSemanticParent
|
||
|
Cursor_semantic_parent.argtypes = [Cursor]
|
||
|
Cursor_semantic_parent.restype = Cursor
|
||
|
Cursor_semantic_parent.errcheck = Cursor.from_result
|
||
|
|
||
|
Cursor_lexical_parent = lib.clang_getCursorLexicalParent
|
||
|
Cursor_lexical_parent.argtypes = [Cursor]
|
||
|
Cursor_lexical_parent.restype = Cursor
|
||
|
Cursor_lexical_parent.errcheck = Cursor.from_result
|
||
|
|
||
|
Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
|
||
|
Cursor_visit = lib.clang_visitChildren
|
||
|
Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
|
||
|
Cursor_visit.restype = c_uint
|
||
|
|
||
|
Cursor_CXXMethod_isStatic = lib.clang_CXXMethod_isStatic
|
||
|
Cursor_CXXMethod_isStatic.argtypes = [Cursor]
|
||
|
Cursor_CXXMethod_isStatic.restype = bool
|
||
|
|
||
|
Cursor_CXXMethod_isVirtual = lib.clang_CXXMethod_isVirtual
|
||
|
Cursor_CXXMethod_isVirtual.argtypes = [Cursor]
|
||
|
Cursor_CXXMethod_isVirtual.restype = bool
|
||
|
|
||
|
Cursor_getCXXAccessSpecifier = lib.clang_getCXXAccessSpecifier
|
||
|
Cursor_getCXXAccessSpecifier.argtypes = [Cursor]
|
||
|
Cursor_getCXXAccessSpecifier.restype = AccessSpecifierKind.from_id
|
||
|
|
||
|
# Type Functions
|
||
|
Type_get_canonical = lib.clang_getCanonicalType
|
||
|
Type_get_canonical.argtypes = [Type]
|
||
|
Type_get_canonical.restype = Type
|
||
|
Type_get_canonical.errcheck = Type.from_result
|
||
|
|
||
|
Type_is_const_qualified = lib.clang_isConstQualifiedType
|
||
|
Type_is_const_qualified.argtypes = [Type]
|
||
|
Type_is_const_qualified.restype = bool
|
||
|
|
||
|
Type_is_volatile_qualified = lib.clang_isVolatileQualifiedType
|
||
|
Type_is_volatile_qualified.argtypes = [Type]
|
||
|
Type_is_volatile_qualified.restype = bool
|
||
|
|
||
|
Type_is_restrict_qualified = lib.clang_isRestrictQualifiedType
|
||
|
Type_is_restrict_qualified.argtypes = [Type]
|
||
|
Type_is_restrict_qualified.restype = bool
|
||
|
|
||
|
Type_is_pod = lib.clang_isPODType
|
||
|
Type_is_pod.argtypes = [Type]
|
||
|
Type_is_pod.restype = bool
|
||
|
|
||
|
Type_is_variadic = lib.clang_isFunctionTypeVariadic
|
||
|
Type_is_variadic.argtypes = [Type]
|
||
|
Type_is_variadic.restype = bool
|
||
|
|
||
|
Type_get_pointee = lib.clang_getPointeeType
|
||
|
Type_get_pointee.argtypes = [Type]
|
||
|
Type_get_pointee.restype = Type
|
||
|
Type_get_pointee.errcheck = Type.from_result
|
||
|
|
||
|
Type_get_declaration = lib.clang_getTypeDeclaration
|
||
|
Type_get_declaration.argtypes = [Type]
|
||
|
Type_get_declaration.restype = Cursor
|
||
|
Type_get_declaration.errcheck = Cursor.from_result
|
||
|
|
||
|
Type_get_result = lib.clang_getResultType
|
||
|
Type_get_result.argtypes = [Type]
|
||
|
Type_get_result.restype = Type
|
||
|
Type_get_result.errcheck = Type.from_result
|
||
|
|
||
|
Type_get_num_arg_types = lib.clang_getNumArgTypes
|
||
|
Type_get_num_arg_types.argtypes = [Type]
|
||
|
Type_get_num_arg_types.restype = c_uint
|
||
|
|
||
|
Type_get_arg_type = lib.clang_getArgType
|
||
|
Type_get_arg_type.argtypes = [Type, c_uint]
|
||
|
Type_get_arg_type.restype = Type
|
||
|
Type_get_arg_type.errcheck = Type.from_result
|
||
|
Type_get_element_type = lib.clang_getElementType
|
||
|
|
||
|
Type_get_element_type.argtypes = [Type]
|
||
|
Type_get_element_type.restype = Type
|
||
|
Type_get_element_type.errcheck = Type.from_result
|
||
|
|
||
|
Type_get_num_elements = lib.clang_getNumElements
|
||
|
Type_get_num_elements.argtypes = [Type]
|
||
|
Type_get_num_elements.restype = c_longlong
|
||
|
|
||
|
Type_get_array_element = lib.clang_getArrayElementType
|
||
|
Type_get_array_element.argtypes = [Type]
|
||
|
Type_get_array_element.restype = Type
|
||
|
Type_get_array_element.errcheck = Type.from_result
|
||
|
|
||
|
Type_get_array_size = lib.clang_getArraySize
|
||
|
Type_get_array_size.argtype = [Type]
|
||
|
Type_get_array_size.restype = c_longlong
|
||
|
|
||
|
Type_equal = lib.clang_equalTypes
|
||
|
Type_equal.argtypes = [Type, Type]
|
||
|
Type_equal.restype = bool
|
||
|
|
||
|
# Index Functions
|
||
|
Index_create = lib.clang_createIndex
|
||
|
Index_create.argtypes = [c_int, c_int]
|
||
|
Index_create.restype = c_object_p
|
||
|
|
||
|
Index_dispose = lib.clang_disposeIndex
|
||
|
Index_dispose.argtypes = [Index]
|
||
|
|
||
|
# Translation Unit Functions
|
||
|
TranslationUnit_read = lib.clang_createTranslationUnit
|
||
|
TranslationUnit_read.argtypes = [Index, c_char_p]
|
||
|
TranslationUnit_read.restype = c_object_p
|
||
|
|
||
|
TranslationUnit_parse = lib.clang_parseTranslationUnit
|
||
|
TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
|
||
|
c_int, c_void_p, c_int, c_int]
|
||
|
TranslationUnit_parse.restype = c_object_p
|
||
|
|
||
|
TranslationUnit_reparse = lib.clang_reparseTranslationUnit
|
||
|
TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
|
||
|
TranslationUnit_reparse.restype = c_int
|
||
|
|
||
|
TranslationUnit_codeComplete = lib.clang_codeCompleteAt
|
||
|
TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
|
||
|
c_int, c_void_p, c_int, c_int]
|
||
|
TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
|
||
|
|
||
|
TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
|
||
|
TranslationUnit_cursor.argtypes = [TranslationUnit]
|
||
|
TranslationUnit_cursor.restype = Cursor
|
||
|
TranslationUnit_cursor.errcheck = Cursor.from_result
|
||
|
|
||
|
TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
|
||
|
TranslationUnit_spelling.argtypes = [TranslationUnit]
|
||
|
TranslationUnit_spelling.restype = _CXString
|
||
|
TranslationUnit_spelling.errcheck = _CXString.from_result
|
||
|
|
||
|
TranslationUnit_dispose = lib.clang_disposeTranslationUnit
|
||
|
TranslationUnit_dispose.argtypes = [TranslationUnit]
|
||
|
|
||
|
TranslationUnit_includes_callback = CFUNCTYPE(None,
|
||
|
c_object_p,
|
||
|
POINTER(SourceLocation),
|
||
|
c_uint, py_object)
|
||
|
TranslationUnit_includes = lib.clang_getInclusions
|
||
|
TranslationUnit_includes.argtypes = [TranslationUnit,
|
||
|
TranslationUnit_includes_callback,
|
||
|
py_object]
|
||
|
|
||
|
TranslationUnit_defaultSaveOptions = lib.clang_defaultSaveOptions
|
||
|
TranslationUnit_defaultSaveOptions.argtypes = [TranslationUnit]
|
||
|
TranslationUnit_defaultSaveOptions.restype = c_uint
|
||
|
|
||
|
TranslationUnit_save = lib.clang_saveTranslationUnit
|
||
|
TranslationUnit_save.argtypes = [TranslationUnit, c_char_p, c_uint]
|
||
|
TranslationUnit_save.restype = c_int
|
||
|
|
||
|
# File Functions
|
||
|
File_getFile = lib.clang_getFile
|
||
|
File_getFile.argtypes = [TranslationUnit, c_char_p]
|
||
|
File_getFile.restype = c_object_p
|
||
|
|
||
|
File_name = lib.clang_getFileName
|
||
|
File_name.argtypes = [File]
|
||
|
File_name.restype = _CXString
|
||
|
|
||
|
File_time = lib.clang_getFileTime
|
||
|
File_time.argtypes = [File]
|
||
|
File_time.restype = c_uint
|
||
|
|
||
|
# Code completion
|
||
|
|
||
|
CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
|
||
|
CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
|
||
|
|
||
|
_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
|
||
|
_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
|
||
|
_clang_codeCompleteGetNumDiagnostics.restype = c_int
|
||
|
|
||
|
_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
|
||
|
_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
|
||
|
_clang_codeCompleteGetDiagnostic.restype = Diagnostic
|
||
|
|
||
|
_clang_getCompletionChunkText = lib.clang_getCompletionChunkText
|
||
|
_clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
|
||
|
_clang_getCompletionChunkText.restype = _CXString
|
||
|
|
||
|
_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
|
||
|
_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
|
||
|
_clang_getCompletionChunkKind.restype = c_int
|
||
|
|
||
|
_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
|
||
|
_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
|
||
|
_clang_getCompletionChunkCompletionString.restype = c_object_p
|
||
|
|
||
|
_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
|
||
|
_clang_getNumCompletionChunks.argtypes = [c_void_p]
|
||
|
_clang_getNumCompletionChunks.restype = c_int
|
||
|
|
||
|
_clang_getCompletionAvailability = lib.clang_getCompletionAvailability
|
||
|
_clang_getCompletionAvailability.argtypes = [c_void_p]
|
||
|
_clang_getCompletionAvailability.restype = c_int
|
||
|
|
||
|
_clang_getCompletionPriority = lib.clang_getCompletionPriority
|
||
|
_clang_getCompletionPriority.argtypes = [c_void_p]
|
||
|
_clang_getCompletionPriority.restype = c_int
|
||
|
|
||
|
|
||
|
__all__ = [
|
||
|
'CodeCompletionResults',
|
||
|
'CursorKind',
|
||
|
'Cursor',
|
||
|
'Diagnostic',
|
||
|
'File',
|
||
|
'FixIt',
|
||
|
'Index',
|
||
|
'SourceLocation',
|
||
|
'SourceRange',
|
||
|
'TranslationUnitLoadError',
|
||
|
'TranslationUnit',
|
||
|
'TypeKind',
|
||
|
'Type',
|
||
|
]
|