aboutsummaryrefslogtreecommitdiff
path: root/bindings/python
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/python')
-rw-r--r--bindings/python/README.txt17
-rw-r--r--bindings/python/clang/__init__.py24
-rw-r--r--bindings/python/clang/cindex.py3414
-rw-r--r--bindings/python/clang/enumerations.py34
-rw-r--r--bindings/python/examples/cindex/cindex-dump.py87
-rw-r--r--bindings/python/examples/cindex/cindex-includes.py58
-rw-r--r--bindings/python/tests/__init__.py0
-rw-r--r--bindings/python/tests/cindex/INPUTS/compile_commands.json17
-rw-r--r--bindings/python/tests/cindex/INPUTS/header1.h6
-rw-r--r--bindings/python/tests/cindex/INPUTS/header2.h6
-rw-r--r--bindings/python/tests/cindex/INPUTS/header3.h3
-rw-r--r--bindings/python/tests/cindex/INPUTS/hello.cpp6
-rw-r--r--bindings/python/tests/cindex/INPUTS/include.cpp5
-rw-r--r--bindings/python/tests/cindex/INPUTS/parse_arguments.c2
-rw-r--r--bindings/python/tests/cindex/__init__.py0
-rw-r--r--bindings/python/tests/cindex/test_cdb.py89
-rw-r--r--bindings/python/tests/cindex/test_code_completion.py75
-rw-r--r--bindings/python/tests/cindex/test_comment.py40
-rw-r--r--bindings/python/tests/cindex/test_cursor.py261
-rw-r--r--bindings/python/tests/cindex/test_cursor_kind.py47
-rw-r--r--bindings/python/tests/cindex/test_diagnostics.py82
-rw-r--r--bindings/python/tests/cindex/test_file.py9
-rw-r--r--bindings/python/tests/cindex/test_index.py15
-rw-r--r--bindings/python/tests/cindex/test_location.py95
-rw-r--r--bindings/python/tests/cindex/test_token_kind.py43
-rw-r--r--bindings/python/tests/cindex/test_tokens.py52
-rw-r--r--bindings/python/tests/cindex/test_translation_unit.py258
-rw-r--r--bindings/python/tests/cindex/test_type.py397
-rw-r--r--bindings/python/tests/cindex/util.py93
29 files changed, 0 insertions, 5235 deletions
diff --git a/bindings/python/README.txt b/bindings/python/README.txt
deleted file mode 100644
index 742cf8fbb8fc..000000000000
--- a/bindings/python/README.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-//===----------------------------------------------------------------------===//
-// Clang Python Bindings
-//===----------------------------------------------------------------------===//
-
-This directory implements Python bindings for Clang.
-
-You may need to alter LD_LIBRARY_PATH so that the Clang library can be
-found. The unit tests are designed to be run with 'nosetests'. For example:
---
-$ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \
- LD_LIBRARY_PATH=$(llvm-config --libdir) \
- nosetests -v
-tests.cindex.test_index.test_create ... ok
-...
-
-OK
---
diff --git a/bindings/python/clang/__init__.py b/bindings/python/clang/__init__.py
deleted file mode 100644
index 88f30812383f..000000000000
--- a/bindings/python/clang/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#===- __init__.py - Clang Python 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 Library Bindings
-======================
-
-This package provides access to the Clang compiler and libraries.
-
-The available modules are:
-
- cindex
-
- Bindings for the Clang indexing library.
-"""
-
-__all__ = ['cindex']
-
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
deleted file mode 100644
index c103c7078003..000000000000
--- a/bindings/python/clang/cindex.py
+++ /dev/null
@@ -1,3414 +0,0 @@
-#===- 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
-
-import clang.enumerations
-
-# 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)
-
-callbacks = {}
-
-### 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 CachedProperty(object):
- """Decorator that lazy-loads the value of a property.
-
- The first time the property is accessed, the original property function is
- executed. The value it returns is set as the new value of that instance's
- property, replacing the original method.
- """
-
- def __init__(self, wrapped):
- self.wrapped = wrapped
- try:
- self.__doc__ = wrapped.__doc__
- except:
- pass
-
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
-
- value = self.wrapped(instance)
- setattr(instance, self.wrapped.__name__, value)
-
- return value
-
-
-class _CXString(Structure):
- """Helper for transforming CXString results."""
-
- _fields_ = [("spelling", c_char_p), ("free", c_int)]
-
- def __del__(self):
- conf.lib.clang_disposeString(self)
-
- @staticmethod
- def from_result(res, fn, args):
- assert isinstance(res, _CXString)
- return conf.lib.clang_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()
- conf.lib.clang_getInstantiationLocation(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 conf.lib.clang_getLocation(tu, file, line, column)
-
- @staticmethod
- def from_offset(tu, file, offset):
- """Retrieve a SourceLocation from a given character offset.
-
- tu -- TranslationUnit file belongs to
- file -- File instance to obtain offset from
- offset -- Integer character offset within file
- """
- return conf.lib.clang_getLocationForOffset(tu, file, offset)
-
- @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 conf.lib.clang_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 conf.lib.clang_getRange(start, end)
-
- @property
- def start(self):
- """
- Return a SourceLocation representing the first character within a
- source range.
- """
- return conf.lib.clang_getRangeStart(self)
-
- @property
- def end(self):
- """
- Return a SourceLocation representing the last character within a
- source range.
- """
- return conf.lib.clang_getRangeEnd(self)
-
- def __eq__(self, other):
- return conf.lib.clang_equalRanges(self, other)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __contains__(self, other):
- """Useful to detect the Token/Lexer bug"""
- if not isinstance(other, SourceLocation):
- return False
- if other.file is None and self.start.file is None:
- pass
- elif ( self.start.file.name != other.file.name or
- other.file.name != self.end.file.name):
- # same file name
- return False
- # same file, in between lines
- if self.start.line < other.line < self.end.line:
- return True
- elif self.start.line == other.line:
- # same file first line
- if self.start.column <= other.column:
- return True
- elif other.line == self.end.line:
- # same file last line
- if other.column <= self.end.column:
- return True
- return False
-
- 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):
- conf.lib.clang_disposeDiagnostic(self)
-
- @property
- def severity(self):
- return conf.lib.clang_getDiagnosticSeverity(self)
-
- @property
- def location(self):
- return conf.lib.clang_getDiagnosticLocation(self)
-
- @property
- def spelling(self):
- return conf.lib.clang_getDiagnosticSpelling(self)
-
- @property
- def ranges(self):
- class RangeIterator:
- def __init__(self, diag):
- self.diag = diag
-
- def __len__(self):
- return int(conf.lib.clang_getDiagnosticNumRanges(self.diag))
-
- def __getitem__(self, key):
- if (key >= len(self)):
- raise IndexError
- return conf.lib.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(conf.lib.clang_getDiagnosticNumFixIts(self.diag))
-
- def __getitem__(self, key):
- range = SourceRange()
- value = conf.lib.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 conf.lib.clang_getDiagnosticCategory(self)
-
- @property
- def category_name(self):
- """The string name of the category for this diagnostic."""
- return conf.lib.clang_getDiagnosticCategoryName(self.category_number)
-
- @property
- def option(self):
- """The command-line option that enables this diagnostic."""
- return conf.lib.clang_getDiagnosticOption(self, None)
-
- @property
- def disable_option(self):
- """The command-line option that disables this diagnostic."""
- disable = _CXString()
- conf.lib.clang_getDiagnosticOption(self, byref(disable))
-
- return conf.lib.clang_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)
-
-class TokenGroup(object):
- """Helper class to facilitate token management.
-
- Tokens are allocated from libclang in chunks. They must be disposed of as a
- collective group.
-
- One purpose of this class is for instances to represent groups of allocated
- tokens. Each token in a group contains a reference back to an instance of
- this class. When all tokens from a group are garbage collected, it allows
- this class to be garbage collected. When this class is garbage collected,
- it calls the libclang destructor which invalidates all tokens in the group.
-
- You should not instantiate this class outside of this module.
- """
- def __init__(self, tu, memory, count):
- self._tu = tu
- self._memory = memory
- self._count = count
-
- def __del__(self):
- conf.lib.clang_disposeTokens(self._tu, self._memory, self._count)
-
- @staticmethod
- def get_tokens(tu, extent):
- """Helper method to return all tokens in an extent.
-
- This functionality is needed multiple places in this module. We define
- it here because it seems like a logical place.
- """
- tokens_memory = POINTER(Token)()
- tokens_count = c_uint()
-
- conf.lib.clang_tokenize(tu, extent, byref(tokens_memory),
- byref(tokens_count))
-
- count = int(tokens_count.value)
-
- # If we get no tokens, no memory was allocated. Be sure not to return
- # anything and potentially call a destructor on nothing.
- if count < 1:
- return
-
- tokens_array = cast(tokens_memory, POINTER(Token * count)).contents
-
- token_group = TokenGroup(tu, tokens_memory, tokens_count)
-
- for i in xrange(0, count):
- token = Token()
- token.int_data = tokens_array[i].int_data
- token.ptr_data = tokens_array[i].ptr_data
- token._tu = tu
- token._group = token_group
-
- yield token
-
-class TokenKind(object):
- """Describes a specific type of a Token."""
-
- _value_map = {} # int -> TokenKind
-
- def __init__(self, value, name):
- """Create a new TokenKind instance from a numeric value and a name."""
- self.value = value
- self.name = name
-
- def __repr__(self):
- return 'TokenKind.%s' % (self.name,)
-
- @staticmethod
- def from_value(value):
- """Obtain a registered TokenKind instance from its value."""
- result = TokenKind._value_map.get(value, None)
-
- if result is None:
- raise ValueError('Unknown TokenKind: %d' % value)
-
- return result
-
- @staticmethod
- def register(value, name):
- """Register a new TokenKind enumeration.
-
- This should only be called at module load time by code within this
- package.
- """
- if value in TokenKind._value_map:
- raise ValueError('TokenKind already registered: %d' % value)
-
- kind = TokenKind(value, name)
- TokenKind._value_map[value] = kind
- setattr(TokenKind, name, kind)
-
-### 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 %d' % id
- 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 conf.lib.clang_isDeclaration(self)
-
- def is_reference(self):
- """Test if this is a reference kind."""
- return conf.lib.clang_isReference(self)
-
- def is_expression(self):
- """Test if this is an expression kind."""
- return conf.lib.clang_isExpression(self)
-
- def is_statement(self):
- """Test if this is a statement kind."""
- return conf.lib.clang_isStatement(self)
-
- def is_attribute(self):
- """Test if this is an attribute kind."""
- return conf.lib.clang_isAttribute(self)
-
- def is_invalid(self):
- """Test if this is an invalid kind."""
- return conf.lib.clang_isInvalid(self)
-
- def is_translation_unit(self):
- """Test if this is a translation unit kind."""
- return conf.lib.clang_isTranslationUnit(self)
-
- def is_preprocessing(self):
- """Test if this is a preprocessing kind."""
- return conf.lib.clang_isPreprocessing(self)
-
- def is_unexposed(self):
- """Test if this is an unexposed kind."""
- return conf.lib.clang_isUnexposed(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_PARAMETER = 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 to 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)
-
-# A reference to a variable that occurs in some non-expression
-# context, e.g., a C++ lambda capture list.
-CursorKind.VARIABLE_REF = CursorKind(50)
-
-###
-# 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.CONDITIONAL_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)
-
-# Represents a C++ lambda expression that produces a local function
-# object.
-#
-# \code
-# void abssort(float *x, unsigned N) {
-# std::sort(x, x + N,
-# [](float a, float b) {
-# return std::abs(a) < std::abs(b);
-# });
-# }
-# \endcode
-CursorKind.LAMBDA_EXPR = CursorKind(144)
-
-# Objective-c Boolean Literal.
-CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145)
-
-# Represents the "self" expression in a ObjC method.
-CursorKind.OBJ_SELF_EXPR = CursorKind(146)
-
-
-# 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)
-
-# A MS inline assembly statement extension.
-CursorKind.MS_ASM_STMT = CursorKind(229)
-
-# 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)
-CursorKind.PACKED_ATTR = CursorKind(408)
-
-###
-# Preprocessing
-CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
-CursorKind.MACRO_DEFINITION = CursorKind(501)
-CursorKind.MACRO_INSTANTIATION = CursorKind(502)
-CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
-
-###
-# Extra declaration
-
-# A module import declaration.
-CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
-
-### 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 = conf.lib.clang_getCursor(tu, location)
- cursor._tu = tu
-
- return cursor
-
- def __eq__(self, other):
- return conf.lib.clang_equalCursors(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 conf.lib.clang_isCursorDefinition(self)
-
- def is_static_method(self):
- """Returns True if the cursor refers to a C++ member function or member
- function template that is declared 'static'.
- """
- return conf.lib.clang_CXXMethod_isStatic(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 conf.lib.clang_getCursorDefinition(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 conf.lib.clang_getCursorUSR(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 = conf.lib.clang_getCursorSpelling(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 = conf.lib.clang_getCursorDisplayName(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 = conf.lib.clang_getCursorLocation(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 = conf.lib.clang_getCursorExtent(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 = conf.lib.clang_getCursorType(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 = conf.lib.clang_getCanonicalCursor(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 = conf.lib.clang_getResultType(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 = \
- conf.lib.clang_getTypedefDeclUnderlyingType(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 = conf.lib.clang_getEnumDeclIntegerType(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 = \
- conf.lib.clang_getEnumConstantDeclUnsignedValue(self)
- else:
- self._enum_value = conf.lib.clang_getEnumConstantDeclValue(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 = \
- conf.lib.clang_getDeclObjCTypeEncoding(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 = conf.lib.clang_hashCursor(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 = conf.lib.clang_getCursorSemanticParent(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 = conf.lib.clang_getCursorLexicalParent(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
-
- @property
- def referenced(self):
- """
- For a cursor that is a reference, returns a cursor
- representing the entity that it references.
- """
- if not hasattr(self, '_referenced'):
- self._referenced = conf.lib.clang_getCursorReferenced(self)
-
- return self._referenced
-
- @property
- def brief_comment(self):
- """Returns the brief comment text associated with that Cursor"""
- return conf.lib.clang_Cursor_getBriefCommentText(self)
-
- @property
- def raw_comment(self):
- """Returns the raw comment text associated with that Cursor"""
- return conf.lib.clang_Cursor_getRawCommentText(self)
-
- def get_arguments(self):
- """Return an iterator for accessing the arguments of this cursor."""
- num_args = conf.lib.clang_Cursor_getNumArguments(self)
- for i in range(0, num_args):
- yield conf.lib.clang_Cursor_getArgument(self, i)
-
- 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 != conf.lib.clang_getNullCursor()
-
- # Create reference to TU so it isn't GC'd before Cursor.
- child._tu = self._tu
- children.append(child)
- return 1 # continue
- children = []
- conf.lib.clang_visitChildren(self, callbacks['cursor_visit'](visitor),
- children)
- return iter(children)
-
- def get_tokens(self):
- """Obtain Token instances formulating that compose this Cursor.
-
- This is a generator for Token instances. It returns all tokens which
- occupy the extent this cursor occupies.
- """
- return TokenGroup.get_tokens(self._tu, self.extent)
-
- def is_bitfield(self):
- """
- Check if the field is a bitfield.
- """
- return conf.lib.clang_Cursor_isBitField(self)
-
- def get_bitfield_width(self):
- """
- Retrieve the width of a bitfield.
- """
- return conf.lib.clang_getFieldDeclBitWidth(self)
-
- @staticmethod
- def from_result(res, fn, args):
- assert isinstance(res, Cursor)
- # FIXME: There should just be an isNull method.
- if res == conf.lib.clang_getNullCursor():
- 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
-
- @staticmethod
- def from_cursor_result(res, fn, args):
- assert isinstance(res, Cursor)
- if res == conf.lib.clang_getNullCursor():
- return None
-
- res._tu = args[0]._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 conf.lib.clang_getTypeKindSpelling(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.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)
-TypeKind.INCOMPLETEARRAY = TypeKind(114)
-TypeKind.VARIABLEARRAY = TypeKind(115)
-TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
-TypeKind.MEMBERPOINTER = TypeKind(117)
-
-class RefQualifierKind(object):
- """Describes a specific ref-qualifier of a type."""
-
- # The unique kind objects, indexed by id.
- _kinds = []
- _name_map = None
-
- def __init__(self, value):
- if value >= len(RefQualifierKind._kinds):
- num_kinds = value - len(RefQualifierKind._kinds) + 1
- RefQualifierKind._kinds += [None] * num_kinds
- if RefQualifierKind._kinds[value] is not None:
- raise ValueError, 'RefQualifierKind already loaded'
- self.value = value
- RefQualifierKind._kinds[value] = self
- RefQualifierKind._name_map = None
-
- def from_param(self):
- return self.value
-
- @property
- def name(self):
- """Get the enumeration name of this kind."""
- if self._name_map is None:
- self._name_map = {}
- for key, value in RefQualifierKind.__dict__.items():
- if isinstance(value, RefQualifierKind):
- self._name_map[value] = key
- return self._name_map[self]
-
- @staticmethod
- def from_id(id):
- if (id >= len(RefQualifierKind._kinds) or
- RefQualifierKind._kinds[id] is None):
- raise ValueError, 'Unknown type kind %d' % id
- return RefQualifierKind._kinds[id]
-
- def __repr__(self):
- return 'RefQualifierKind.%s' % (self.name,)
-
-RefQualifierKind.NONE = RefQualifierKind(0)
-RefQualifierKind.LVALUE = RefQualifierKind(1)
-RefQualifierKind.RVALUE = RefQualifierKind(2)
-
-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 = conf.lib.clang_getNumArgTypes(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 = conf.lib.clang_getArgType(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 = conf.lib.clang_getElementType(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 = conf.lib.clang_getNumElements(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 conf.lib.clang_getCanonicalType(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 conf.lib.clang_isConstQualifiedType(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 conf.lib.clang_isVolatileQualifiedType(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 conf.lib.clang_isRestrictQualifiedType(self)
-
- def is_function_variadic(self):
- """Determine whether this function Type is a variadic function type."""
- assert self.kind == TypeKind.FUNCTIONPROTO
-
- return conf.lib.clang_isFunctionTypeVariadic(self)
-
- def is_pod(self):
- """Determine whether this Type represents plain old data (POD)."""
- return conf.lib.clang_isPODType(self)
-
- def get_pointee(self):
- """
- For pointer types, returns the type of the pointee.
- """
- return conf.lib.clang_getPointeeType(self)
-
- def get_declaration(self):
- """
- Return the cursor for the declaration of the given type.
- """
- return conf.lib.clang_getTypeDeclaration(self)
-
- def get_result(self):
- """
- Retrieve the result type associated with a function type.
- """
- return conf.lib.clang_getResultType(self)
-
- def get_array_element_type(self):
- """
- Retrieve the type of the elements of the array type.
- """
- return conf.lib.clang_getArrayElementType(self)
-
- def get_array_size(self):
- """
- Retrieve the size of the constant array.
- """
- return conf.lib.clang_getArraySize(self)
-
- def get_class_type(self):
- """
- Retrieve the class type of the member pointer type.
- """
- return conf.lib.clang_Type_getClassType(self)
-
- def get_align(self):
- """
- Retrieve the alignment of the record.
- """
- return conf.lib.clang_Type_getAlignOf(self)
-
- def get_size(self):
- """
- Retrieve the size of the record.
- """
- return conf.lib.clang_Type_getSizeOf(self)
-
- def get_offset(self, fieldname):
- """
- Retrieve the offset of a field in the record.
- """
- return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
-
- def get_ref_qualifier(self):
- """
- Retrieve the ref-qualifier of the type.
- """
- return RefQualifierKind.from_id(
- conf.lib.clang_Type_getCXXRefQualifier(self))
-
- @property
- def spelling(self):
- """Retrieve the spelling of this Type."""
- return conf.lib.clang_getTypeSpelling(self)
-
- def __eq__(self, other):
- if type(other) != type(self):
- return False
-
- return conf.lib.clang_equalTypes(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)]
-
-# Functions calls through the python interface are rather slow. Fortunately,
-# for most symboles, we do not need to perform a function call. Their spelling
-# never changes and is consequently provided by this spelling cache.
-SpellingCache = {
- # 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 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
- self.__kindNumberCache = -1
-
- def __repr__(self):
- return "{'" + self.spelling + "', " + str(self.kind) + "}"
-
- @CachedProperty
- def spelling(self):
- if self.__kindNumber in SpellingCache:
- return SpellingCache[self.__kindNumber]
- return conf.lib.clang_getCompletionChunkText(self.cs, self.key).spelling
-
- # We do not use @CachedProperty here, as the manual implementation is
- # apparently still significantly faster. Please profile carefully if you
- # would like to add CachedProperty back.
- @property
- def __kindNumber(self):
- if self.__kindNumberCache == -1:
- self.__kindNumberCache = \
- conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
- return self.__kindNumberCache
-
- @CachedProperty
- def kind(self):
- return completionChunkKindMap[self.__kindNumber]
-
- @CachedProperty
- def string(self):
- res = conf.lib.clang_getCompletionChunkCompletionString(self.cs,
- self.key)
-
- if (res):
- return CompletionString(res)
- else:
- None
-
- def isKindOptional(self):
- return self.__kindNumber == 0
-
- def isKindTypedText(self):
- return self.__kindNumber == 1
-
- def isKindPlaceHolder(self):
- return self.__kindNumber == 3
-
- def isKindInformative(self):
- return self.__kindNumber == 4
-
- def isKindResultType(self):
- return self.__kindNumber == 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):
- self.num_chunks
-
- @CachedProperty
- def num_chunks(self):
- return conf.lib.clang_getNumCompletionChunks(self.obj)
-
- def __getitem__(self, key):
- if self.num_chunks <= key:
- raise IndexError
- return CompletionChunk(self.obj, key)
-
- @property
- def priority(self):
- return conf.lib.clang_getCompletionPriority(self.obj)
-
- @property
- def availability(self):
- res = conf.lib.clang_getCompletionAvailability(self.obj)
- return availabilityKinds[res]
-
- @property
- def briefComment(self):
- if conf.function_exists("clang_getCompletionBriefComment"):
- return conf.lib.clang_getCompletionBriefComment(self.obj)
- return _CXString()
-
- def __repr__(self):
- return " | ".join([str(a) for a in self]) \
- + " || Priority: " + str(self.priority) \
- + " || Availability: " + str(self.availability) \
- + " || Brief comment: " + str(self.briefComment.spelling)
-
-availabilityKinds = {
- 0: CompletionChunk.Kind("Available"),
- 1: CompletionChunk.Kind("Deprecated"),
- 2: CompletionChunk.Kind("NotAvailable"),
- 3: CompletionChunk.Kind("NotAccessible")}
-
-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):
- conf.lib.clang_disposeCodeCompleteResults(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(\
- conf.lib.clang_codeCompleteGetNumDiagnostics(self.ccr))
-
- def __getitem__(self, key):
- return conf.lib.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(conf.lib.clang_createIndex(excludeDecls, 0))
-
- def __del__(self):
- conf.lib.clang_disposeIndex(self)
-
- def read(self, path):
- """Load a TranslationUnit from the given AST file."""
- return TranslationUnit.from_ast_file(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
-
- # Used to indicate that brief documentation comments should be included
- # into the set of code completions returned from this translation unit.
- PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION = 128
-
- @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 = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
- len(args), unsaved_array,
- len(unsaved_files), options)
-
- if not ptr:
- 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 = conf.lib.clang_createTranslationUnit(index, filename)
- if not ptr:
- 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):
- conf.lib.clang_disposeTranslationUnit(self)
-
- @property
- def cursor(self):
- """Retrieve the cursor that represents the given translation unit."""
- return conf.lib.clang_getTranslationUnitCursor(self)
-
- @property
- def spelling(self):
- """Get the original translation unit source file name."""
- return conf.lib.clang_getTranslationUnitSpelling(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 = []
- conf.lib.clang_getInclusions(self,
- callbacks['translation_unit_includes'](visitor), includes)
-
- return iter(includes)
-
- def get_file(self, filename):
- """Obtain a File from this translation unit."""
-
- return File.from_name(self, filename)
-
- def get_location(self, filename, position):
- """Obtain a SourceLocation for a file in this translation unit.
-
- The position can be specified by passing:
-
- - Integer file offset. Initial file offset is 0.
- - 2-tuple of (line number, column number). Initial file position is
- (0, 0)
- """
- f = self.get_file(filename)
-
- if isinstance(position, int):
- return SourceLocation.from_offset(self, f, position)
-
- return SourceLocation.from_position(self, f, position[0], position[1])
-
- def get_extent(self, filename, locations):
- """Obtain a SourceRange from this translation unit.
-
- The bounds of the SourceRange must ultimately be defined by a start and
- end SourceLocation. For the locations argument, you can pass:
-
- - 2 SourceLocation instances in a 2-tuple or list.
- - 2 int file offsets via a 2-tuple or list.
- - 2 2-tuple or lists of (line, column) pairs in a 2-tuple or list.
-
- e.g.
-
- get_extent('foo.c', (5, 10))
- get_extent('foo.c', ((1, 1), (1, 15)))
- """
- f = self.get_file(filename)
-
- if len(locations) < 2:
- raise Exception('Must pass object with at least 2 elements')
-
- start_location, end_location = locations
-
- if hasattr(start_location, '__len__'):
- start_location = SourceLocation.from_position(self, f,
- start_location[0], start_location[1])
- elif isinstance(start_location, int):
- start_location = SourceLocation.from_offset(self, f,
- start_location)
-
- if hasattr(end_location, '__len__'):
- end_location = SourceLocation.from_position(self, f,
- end_location[0], end_location[1])
- elif isinstance(end_location, int):
- end_location = SourceLocation.from_offset(self, f, end_location)
-
- assert isinstance(start_location, SourceLocation)
- assert isinstance(end_location, SourceLocation)
-
- return SourceRange.from_locations(start_location, end_location)
-
- @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(conf.lib.clang_getNumDiagnostics(self.tu))
-
- def __getitem__(self, key):
- diag = conf.lib.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 = conf.lib.clang_reparseTranslationUnit(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 = conf.lib.clang_defaultSaveOptions(self)
- result = int(conf.lib.clang_saveTranslationUnit(self, filename,
- options))
- if result != 0:
- raise TranslationUnitSaveError(result,
- 'Error saving TranslationUnit.')
-
- def codeComplete(self, path, line, column, unsaved_files=None,
- include_macros=False, include_code_patterns=False,
- include_brief_comments=False):
- """
- 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.
- """
- options = 0
-
- if include_macros:
- options += 1
-
- if include_code_patterns:
- options += 2
-
- if include_brief_comments:
- options += 4
-
- 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 = conf.lib.clang_codeCompleteAt(self, path, line, column,
- unsaved_files_array, len(unsaved_files), options)
- if ptr:
- return CodeCompletionResults(ptr)
- return None
-
- def get_tokens(self, locations=None, extent=None):
- """Obtain tokens in this translation unit.
-
- This is a generator for Token instances. The caller specifies a range
- of source code to obtain tokens for. The range can be specified as a
- 2-tuple of SourceLocation or as a SourceRange. If both are defined,
- behavior is undefined.
- """
- if locations is not None:
- extent = SourceRange(start=locations[0], end=locations[1])
-
- return TokenGroup.get_tokens(self, extent)
-
-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(conf.lib.clang_getFile(translation_unit, file_name))
-
- @property
- def name(self):
- """Return the complete file and path name of the file."""
- return conf.lib.clang_getCString(conf.lib.clang_getFileName(self))
-
- @property
- def time(self):
- """Return the last modification time of the file."""
- return conf.lib.clang_getFileTime(self)
-
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return "<File: %s>" % (self.name)
-
- @staticmethod
- def from_cursor_result(res, fn, args):
- assert isinstance(res, File)
-
- # Copy a reference to the TranslationUnit to prevent premature GC.
- res._tu = args[0]._tu
- return res
-
-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
-
-class CompilationDatabaseError(Exception):
- """Represents an error that occurred when working with a CompilationDatabase
-
- Each error is associated to an enumerated value, accessible under
- e.cdb_error. Consumers can compare the value with one of the ERROR_
- constants in this class.
- """
-
- # An unknown error occured
- ERROR_UNKNOWN = 0
-
- # The database could not be loaded
- ERROR_CANNOTLOADDATABASE = 1
-
- def __init__(self, enumeration, message):
- assert isinstance(enumeration, int)
-
- if enumeration > 1:
- raise Exception("Encountered undefined CompilationDatabase error "
- "constant: %d. Please file a bug to have this "
- "value supported." % enumeration)
-
- self.cdb_error = enumeration
- Exception.__init__(self, 'Error %d: %s' % (enumeration, message))
-
-class CompileCommand(object):
- """Represents the compile command used to build a file"""
- def __init__(self, cmd, ccmds):
- self.cmd = cmd
- # Keep a reference to the originating CompileCommands
- # to prevent garbage collection
- self.ccmds = ccmds
-
- @property
- def directory(self):
- """Get the working directory for this CompileCommand"""
- return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
-
- @property
- def arguments(self):
- """
- Get an iterable object providing each argument in the
- command line for the compiler invocation as a _CXString.
-
- Invariant : the first argument is the compiler executable
- """
- length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
- for i in xrange(length):
- yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
-
-class CompileCommands(object):
- """
- CompileCommands is an iterable object containing all CompileCommand
- that can be used for building a specific file.
- """
- def __init__(self, ccmds):
- self.ccmds = ccmds
-
- def __del__(self):
- conf.lib.clang_CompileCommands_dispose(self.ccmds)
-
- def __len__(self):
- return int(conf.lib.clang_CompileCommands_getSize(self.ccmds))
-
- def __getitem__(self, i):
- cc = conf.lib.clang_CompileCommands_getCommand(self.ccmds, i)
- if not cc:
- raise IndexError
- return CompileCommand(cc, self)
-
- @staticmethod
- def from_result(res, fn, args):
- if not res:
- return None
- return CompileCommands(res)
-
-class CompilationDatabase(ClangObject):
- """
- The CompilationDatabase is a wrapper class around
- clang::tooling::CompilationDatabase
-
- It enables querying how a specific source file can be built.
- """
-
- def __del__(self):
- conf.lib.clang_CompilationDatabase_dispose(self)
-
- @staticmethod
- def from_result(res, fn, args):
- if not res:
- raise CompilationDatabaseError(0,
- "CompilationDatabase loading failed")
- return CompilationDatabase(res)
-
- @staticmethod
- def fromDirectory(buildDir):
- """Builds a CompilationDatabase from the database found in buildDir"""
- errorCode = c_uint()
- try:
- cdb = conf.lib.clang_CompilationDatabase_fromDirectory(buildDir,
- byref(errorCode))
- except CompilationDatabaseError as e:
- raise CompilationDatabaseError(int(errorCode.value),
- "CompilationDatabase loading failed")
- return cdb
-
- def getCompileCommands(self, filename):
- """
- Get an iterable object providing all the CompileCommands available to
- build filename. Returns None if filename is not found in the database.
- """
- return conf.lib.clang_CompilationDatabase_getCompileCommands(self,
- filename)
-
-class Token(Structure):
- """Represents a single token from the preprocessor.
-
- Tokens are effectively segments of source code. Source code is first parsed
- into tokens before being converted into the AST and Cursors.
-
- Tokens are obtained from parsed TranslationUnit instances. You currently
- can't create tokens manually.
- """
- _fields_ = [
- ('int_data', c_uint * 4),
- ('ptr_data', c_void_p)
- ]
-
- @property
- def spelling(self):
- """The spelling of this token.
-
- This is the textual representation of the token in source.
- """
- return conf.lib.clang_getTokenSpelling(self._tu, self)
-
- @property
- def kind(self):
- """Obtain the TokenKind of the current token."""
- return TokenKind.from_value(conf.lib.clang_getTokenKind(self))
-
- @property
- def location(self):
- """The SourceLocation this Token occurs at."""
- return conf.lib.clang_getTokenLocation(self._tu, self)
-
- @property
- def extent(self):
- """The SourceRange this Token occupies."""
- return conf.lib.clang_getTokenExtent(self._tu, self)
-
- @property
- def cursor(self):
- """The Cursor this Token corresponds to."""
- cursor = Cursor()
-
- conf.lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor))
-
- return cursor
-
-# Now comes the plumbing to hook up the C library.
-
-# Register callback types in common container.
-callbacks['translation_unit_includes'] = CFUNCTYPE(None, c_object_p,
- POINTER(SourceLocation), c_uint, py_object)
-callbacks['cursor_visit'] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
-
-# Functions strictly alphabetical order.
-functionList = [
- ("clang_annotateTokens",
- [TranslationUnit, POINTER(Token), c_uint, POINTER(Cursor)]),
-
- ("clang_CompilationDatabase_dispose",
- [c_object_p]),
-
- ("clang_CompilationDatabase_fromDirectory",
- [c_char_p, POINTER(c_uint)],
- c_object_p,
- CompilationDatabase.from_result),
-
- ("clang_CompilationDatabase_getCompileCommands",
- [c_object_p, c_char_p],
- c_object_p,
- CompileCommands.from_result),
-
- ("clang_CompileCommands_dispose",
- [c_object_p]),
-
- ("clang_CompileCommands_getCommand",
- [c_object_p, c_uint],
- c_object_p),
-
- ("clang_CompileCommands_getSize",
- [c_object_p],
- c_uint),
-
- ("clang_CompileCommand_getArg",
- [c_object_p, c_uint],
- _CXString,
- _CXString.from_result),
-
- ("clang_CompileCommand_getDirectory",
- [c_object_p],
- _CXString,
- _CXString.from_result),
-
- ("clang_CompileCommand_getNumArgs",
- [c_object_p],
- c_uint),
-
- ("clang_codeCompleteAt",
- [TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int],
- POINTER(CCRStructure)),
-
- ("clang_codeCompleteGetDiagnostic",
- [CodeCompletionResults, c_int],
- Diagnostic),
-
- ("clang_codeCompleteGetNumDiagnostics",
- [CodeCompletionResults],
- c_int),
-
- ("clang_createIndex",
- [c_int, c_int],
- c_object_p),
-
- ("clang_createTranslationUnit",
- [Index, c_char_p],
- c_object_p),
-
- ("clang_CXXMethod_isPureVirtual",
- [Cursor],
- bool),
-
- ("clang_CXXMethod_isStatic",
- [Cursor],
- bool),
-
- ("clang_CXXMethod_isVirtual",
- [Cursor],
- bool),
-
- ("clang_defaultSaveOptions",
- [TranslationUnit],
- c_uint),
-
- ("clang_disposeCodeCompleteResults",
- [CodeCompletionResults]),
-
-# ("clang_disposeCXTUResourceUsage",
-# [CXTUResourceUsage]),
-
- ("clang_disposeDiagnostic",
- [Diagnostic]),
-
- ("clang_disposeIndex",
- [Index]),
-
- ("clang_disposeString",
- [_CXString]),
-
- ("clang_disposeTokens",
- [TranslationUnit, POINTER(Token), c_uint]),
-
- ("clang_disposeTranslationUnit",
- [TranslationUnit]),
-
- ("clang_equalCursors",
- [Cursor, Cursor],
- bool),
-
- ("clang_equalLocations",
- [SourceLocation, SourceLocation],
- bool),
-
- ("clang_equalRanges",
- [SourceRange, SourceRange],
- bool),
-
- ("clang_equalTypes",
- [Type, Type],
- bool),
-
- ("clang_getArgType",
- [Type, c_uint],
- Type,
- Type.from_result),
-
- ("clang_getArrayElementType",
- [Type],
- Type,
- Type.from_result),
-
- ("clang_getArraySize",
- [Type],
- c_longlong),
-
- ("clang_getFieldDeclBitWidth",
- [Cursor],
- c_int),
-
- ("clang_getCanonicalCursor",
- [Cursor],
- Cursor,
- Cursor.from_cursor_result),
-
- ("clang_getCanonicalType",
- [Type],
- Type,
- Type.from_result),
-
- ("clang_getCompletionAvailability",
- [c_void_p],
- c_int),
-
- ("clang_getCompletionBriefComment",
- [c_void_p],
- _CXString),
-
- ("clang_getCompletionChunkCompletionString",
- [c_void_p, c_int],
- c_object_p),
-
- ("clang_getCompletionChunkKind",
- [c_void_p, c_int],
- c_int),
-
- ("clang_getCompletionChunkText",
- [c_void_p, c_int],
- _CXString),
-
- ("clang_getCompletionPriority",
- [c_void_p],
- c_int),
-
- ("clang_getCString",
- [_CXString],
- c_char_p),
-
- ("clang_getCursor",
- [TranslationUnit, SourceLocation],
- Cursor),
-
- ("clang_getCursorDefinition",
- [Cursor],
- Cursor,
- Cursor.from_result),
-
- ("clang_getCursorDisplayName",
- [Cursor],
- _CXString,
- _CXString.from_result),
-
- ("clang_getCursorExtent",
- [Cursor],
- SourceRange),
-
- ("clang_getCursorLexicalParent",
- [Cursor],
- Cursor,
- Cursor.from_cursor_result),
-
- ("clang_getCursorLocation",
- [Cursor],
- SourceLocation),
-
- ("clang_getCursorReferenced",
- [Cursor],
- Cursor,
- Cursor.from_result),
-
- ("clang_getCursorReferenceNameRange",
- [Cursor, c_uint, c_uint],
- SourceRange),
-
- ("clang_getCursorSemanticParent",
- [Cursor],
- Cursor,
- Cursor.from_cursor_result),
-
- ("clang_getCursorSpelling",
- [Cursor],
- _CXString,
- _CXString.from_result),
-
- ("clang_getCursorType",
- [Cursor],
- Type,
- Type.from_result),
-
- ("clang_getCursorUSR",
- [Cursor],
- _CXString,
- _CXString.from_result),
-
-# ("clang_getCXTUResourceUsage",
-# [TranslationUnit],
-# CXTUResourceUsage),
-
- ("clang_getCXXAccessSpecifier",
- [Cursor],
- c_uint),
-
- ("clang_getDeclObjCTypeEncoding",
- [Cursor],
- _CXString,
- _CXString.from_result),
-
- ("clang_getDiagnostic",
- [c_object_p, c_uint],
- c_object_p),
-
- ("clang_getDiagnosticCategory",
- [Diagnostic],
- c_uint),
-
- ("clang_getDiagnosticCategoryName",
- [c_uint],
- _CXString,
- _CXString.from_result),
-
- ("clang_getDiagnosticFixIt",
- [Diagnostic, c_uint, POINTER(SourceRange)],
- _CXString,
- _CXString.from_result),
-
- ("clang_getDiagnosticLocation",
- [Diagnostic],
- SourceLocation),
-
- ("clang_getDiagnosticNumFixIts",
- [Diagnostic],
- c_uint),
-
- ("clang_getDiagnosticNumRanges",
- [Diagnostic],
- c_uint),
-
- ("clang_getDiagnosticOption",
- [Diagnostic, POINTER(_CXString)],
- _CXString,
- _CXString.from_result),
-
- ("clang_getDiagnosticRange",
- [Diagnostic, c_uint],
- SourceRange),
-
- ("clang_getDiagnosticSeverity",
- [Diagnostic],
- c_int),
-
- ("clang_getDiagnosticSpelling",
- [Diagnostic],
- _CXString,
- _CXString.from_result),
-
- ("clang_getElementType",
- [Type],
- Type,
- Type.from_result),
-
- ("clang_getEnumConstantDeclUnsignedValue",
- [Cursor],
- c_ulonglong),
-
- ("clang_getEnumConstantDeclValue",
- [Cursor],
- c_longlong),
-
- ("clang_getEnumDeclIntegerType",
- [Cursor],
- Type,
- Type.from_result),
-
- ("clang_getFile",
- [TranslationUnit, c_char_p],
- c_object_p),
-
- ("clang_getFileName",
- [File],
- _CXString), # TODO go through _CXString.from_result?
-
- ("clang_getFileTime",
- [File],
- c_uint),
-
- ("clang_getIBOutletCollectionType",
- [Cursor],
- Type,
- Type.from_result),
-
- ("clang_getIncludedFile",
- [Cursor],
- File,
- File.from_cursor_result),
-
- ("clang_getInclusions",
- [TranslationUnit, callbacks['translation_unit_includes'], py_object]),
-
- ("clang_getInstantiationLocation",
- [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint),
- POINTER(c_uint)]),
-
- ("clang_getLocation",
- [TranslationUnit, File, c_uint, c_uint],
- SourceLocation),
-
- ("clang_getLocationForOffset",
- [TranslationUnit, File, c_uint],
- SourceLocation),
-
- ("clang_getNullCursor",
- None,
- Cursor),
-
- ("clang_getNumArgTypes",
- [Type],
- c_uint),
-
- ("clang_getNumCompletionChunks",
- [c_void_p],
- c_int),
-
- ("clang_getNumDiagnostics",
- [c_object_p],
- c_uint),
-
- ("clang_getNumElements",
- [Type],
- c_longlong),
-
- ("clang_getNumOverloadedDecls",
- [Cursor],
- c_uint),
-
- ("clang_getOverloadedDecl",
- [Cursor, c_uint],
- Cursor,
- Cursor.from_cursor_result),
-
- ("clang_getPointeeType",
- [Type],
- Type,
- Type.from_result),
-
- ("clang_getRange",
- [SourceLocation, SourceLocation],
- SourceRange),
-
- ("clang_getRangeEnd",
- [SourceRange],
- SourceLocation),
-
- ("clang_getRangeStart",
- [SourceRange],
- SourceLocation),
-
- ("clang_getResultType",
- [Type],
- Type,
- Type.from_result),
-
- ("clang_getSpecializedCursorTemplate",
- [Cursor],
- Cursor,
- Cursor.from_cursor_result),
-
- ("clang_getTemplateCursorKind",
- [Cursor],
- c_uint),
-
- ("clang_getTokenExtent",
- [TranslationUnit, Token],
- SourceRange),
-
- ("clang_getTokenKind",
- [Token],
- c_uint),
-
- ("clang_getTokenLocation",
- [TranslationUnit, Token],
- SourceLocation),
-
- ("clang_getTokenSpelling",
- [TranslationUnit, Token],
- _CXString,
- _CXString.from_result),
-
- ("clang_getTranslationUnitCursor",
- [TranslationUnit],
- Cursor,
- Cursor.from_result),
-
- ("clang_getTranslationUnitSpelling",
- [TranslationUnit],
- _CXString,
- _CXString.from_result),
-
- ("clang_getTUResourceUsageName",
- [c_uint],
- c_char_p),
-
- ("clang_getTypeDeclaration",
- [Type],
- Cursor,
- Cursor.from_result),
-
- ("clang_getTypedefDeclUnderlyingType",
- [Cursor],
- Type,
- Type.from_result),
-
- ("clang_getTypeKindSpelling",
- [c_uint],
- _CXString,
- _CXString.from_result),
-
- ("clang_getTypeSpelling",
- [Type],
- _CXString,
- _CXString.from_result),
-
- ("clang_hashCursor",
- [Cursor],
- c_uint),
-
- ("clang_isAttribute",
- [CursorKind],
- bool),
-
- ("clang_isConstQualifiedType",
- [Type],
- bool),
-
- ("clang_isCursorDefinition",
- [Cursor],
- bool),
-
- ("clang_isDeclaration",
- [CursorKind],
- bool),
-
- ("clang_isExpression",
- [CursorKind],
- bool),
-
- ("clang_isFileMultipleIncludeGuarded",
- [TranslationUnit, File],
- bool),
-
- ("clang_isFunctionTypeVariadic",
- [Type],
- bool),
-
- ("clang_isInvalid",
- [CursorKind],
- bool),
-
- ("clang_isPODType",
- [Type],
- bool),
-
- ("clang_isPreprocessing",
- [CursorKind],
- bool),
-
- ("clang_isReference",
- [CursorKind],
- bool),
-
- ("clang_isRestrictQualifiedType",
- [Type],
- bool),
-
- ("clang_isStatement",
- [CursorKind],
- bool),
-
- ("clang_isTranslationUnit",
- [CursorKind],
- bool),
-
- ("clang_isUnexposed",
- [CursorKind],
- bool),
-
- ("clang_isVirtualBase",
- [Cursor],
- bool),
-
- ("clang_isVolatileQualifiedType",
- [Type],
- bool),
-
- ("clang_parseTranslationUnit",
- [Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int],
- c_object_p),
-
- ("clang_reparseTranslationUnit",
- [TranslationUnit, c_int, c_void_p, c_int],
- c_int),
-
- ("clang_saveTranslationUnit",
- [TranslationUnit, c_char_p, c_uint],
- c_int),
-
- ("clang_tokenize",
- [TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)]),
-
- ("clang_visitChildren",
- [Cursor, callbacks['cursor_visit'], py_object],
- c_uint),
-
- ("clang_Cursor_getNumArguments",
- [Cursor],
- c_int),
-
- ("clang_Cursor_getArgument",
- [Cursor, c_uint],
- Cursor,
- Cursor.from_result),
-
- ("clang_Cursor_isBitField",
- [Cursor],
- bool),
-
- ("clang_Cursor_getBriefCommentText",
- [Cursor],
- _CXString,
- _CXString.from_result),
-
- ("clang_Cursor_getRawCommentText",
- [Cursor],
- _CXString,
- _CXString.from_result),
-
- ("clang_Type_getAlignOf",
- [Type],
- c_longlong),
-
- ("clang_Type_getClassType",
- [Type],
- Type,
- Type.from_result),
-
- ("clang_Type_getOffsetOf",
- [Type, c_char_p],
- c_longlong),
-
- ("clang_Type_getSizeOf",
- [Type],
- c_longlong),
-
- ("clang_Type_getCXXRefQualifier",
- [Type],
- c_uint),
-]
-
-class LibclangError(Exception):
- def __init__(self, message):
- self.m = message
-
- def __str__(self):
- return self.m
-
-def register_function(lib, item, ignore_errors):
- # A function may not exist, if these bindings are used with an older or
- # incompatible version of libclang.so.
- try:
- func = getattr(lib, item[0])
- except AttributeError as e:
- msg = str(e) + ". Please ensure that your python bindings are "\
- "compatible with your libclang.so version."
- if ignore_errors:
- return
- raise LibclangError(msg)
-
- if len(item) >= 2:
- func.argtypes = item[1]
-
- if len(item) >= 3:
- func.restype = item[2]
-
- if len(item) == 4:
- func.errcheck = item[3]
-
-def register_functions(lib, ignore_errors):
- """Register function prototypes with a libclang library instance.
-
- This must be called as part of library instantiation so Python knows how
- to call out to the shared library.
- """
-
- def register(item):
- return register_function(lib, item, ignore_errors)
-
- map(register, functionList)
-
-class Config:
- library_path = None
- library_file = None
- compatibility_check = True
- loaded = False
-
- @staticmethod
- def set_library_path(path):
- """Set the path in which to search for libclang"""
- if Config.loaded:
- raise Exception("library path must be set before before using " \
- "any other functionalities in libclang.")
-
- Config.library_path = path
-
- @staticmethod
- def set_library_file(filename):
- """Set the exact location of libclang"""
- if Config.loaded:
- raise Exception("library file must be set before before using " \
- "any other functionalities in libclang.")
-
- Config.library_file = filename
-
- @staticmethod
- def set_compatibility_check(check_status):
- """ Perform compatibility check when loading libclang
-
- The python bindings are only tested and evaluated with the version of
- libclang they are provided with. To ensure correct behavior a (limited)
- compatibility check is performed when loading the bindings. This check
- will throw an exception, as soon as it fails.
-
- In case these bindings are used with an older version of libclang, parts
- that have been stable between releases may still work. Users of the
- python bindings can disable the compatibility check. This will cause
- the python bindings to load, even though they are written for a newer
- version of libclang. Failures now arise if unsupported or incompatible
- features are accessed. The user is required to test himself if the
- features he is using are available and compatible between different
- libclang versions.
- """
- if Config.loaded:
- raise Exception("compatibility_check must be set before before " \
- "using any other functionalities in libclang.")
-
- Config.compatibility_check = check_status
-
- @CachedProperty
- def lib(self):
- lib = self.get_cindex_library()
- register_functions(lib, not Config.compatibility_check)
- Config.loaded = True
- return lib
-
- def get_filename(self):
- if Config.library_file:
- return Config.library_file
-
- import platform
- name = platform.system()
-
- if name == 'Darwin':
- file = 'libclang.dylib'
- elif name == 'Windows':
- file = 'libclang.dll'
- else:
- file = 'libclang.so'
-
- if Config.library_path:
- file = Config.library_path + '/' + file
-
- return file
-
- def get_cindex_library(self):
- try:
- library = cdll.LoadLibrary(self.get_filename())
- except OSError as e:
- msg = str(e) + ". To provide a path to libclang use " \
- "Config.set_library_path() or " \
- "Config.set_library_file()."
- raise LibclangError(msg)
-
- return library
-
- def function_exists(self, name):
- try:
- getattr(self.lib, name)
- except AttributeError:
- return False
-
- return True
-
-def register_enumerations():
- for name, value in clang.enumerations.TokenKinds:
- TokenKind.register(value, name)
-
-conf = Config()
-register_enumerations()
-
-__all__ = [
- 'Config',
- 'CodeCompletionResults',
- 'CompilationDatabase',
- 'CompileCommands',
- 'CompileCommand',
- 'CursorKind',
- 'Cursor',
- 'Diagnostic',
- 'File',
- 'FixIt',
- 'Index',
- 'SourceLocation',
- 'SourceRange',
- 'TokenKind',
- 'Token',
- 'TranslationUnitLoadError',
- 'TranslationUnit',
- 'TypeKind',
- 'Type',
-]
diff --git a/bindings/python/clang/enumerations.py b/bindings/python/clang/enumerations.py
deleted file mode 100644
index a86a48ade3bd..000000000000
--- a/bindings/python/clang/enumerations.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#===- enumerations.py - Python Enumerations ------------------*- python -*--===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-"""
-Clang Enumerations
-==================
-
-This module provides static definitions of enumerations that exist in libclang.
-
-Enumerations are typically defined as a list of tuples. The exported values are
-typically munged into other types or classes at module load time.
-
-All enumerations are centrally defined in this file so they are all grouped
-together and easier to audit. And, maybe even one day this file will be
-automatically generated by scanning the libclang headers!
-"""
-
-# Maps to CXTokenKind. Note that libclang maintains a separate set of token
-# enumerations from the C++ API.
-TokenKinds = [
- ('PUNCTUATION', 0),
- ('KEYWORD', 1),
- ('IDENTIFIER', 2),
- ('LITERAL', 3),
- ('COMMENT', 4),
-]
-
-__all__ = ['TokenKinds']
diff --git a/bindings/python/examples/cindex/cindex-dump.py b/bindings/python/examples/cindex/cindex-dump.py
deleted file mode 100644
index af7ddab6ea53..000000000000
--- a/bindings/python/examples/cindex/cindex-dump.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-
-#===- cindex-dump.py - cindex/Python Source Dump -------------*- python -*--===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-"""
-A simple command line tool for dumping a source file using the Clang Index
-Library.
-"""
-
-def get_diag_info(diag):
- return { 'severity' : diag.severity,
- 'location' : diag.location,
- 'spelling' : diag.spelling,
- 'ranges' : diag.ranges,
- 'fixits' : diag.fixits }
-
-def get_cursor_id(cursor, cursor_list = []):
- if not opts.showIDs:
- return None
-
- if cursor is None:
- return None
-
- # FIXME: This is really slow. It would be nice if the index API exposed
- # something that let us hash cursors.
- for i,c in enumerate(cursor_list):
- if cursor == c:
- return i
- cursor_list.append(cursor)
- return len(cursor_list) - 1
-
-def get_info(node, depth=0):
- if opts.maxDepth is not None and depth >= opts.maxDepth:
- children = None
- else:
- children = [get_info(c, depth+1)
- for c in node.get_children()]
- return { 'id' : get_cursor_id(node),
- 'kind' : node.kind,
- 'usr' : node.get_usr(),
- 'spelling' : node.spelling,
- 'location' : node.location,
- 'extent.start' : node.extent.start,
- 'extent.end' : node.extent.end,
- 'is_definition' : node.is_definition(),
- 'definition id' : get_cursor_id(node.get_definition()),
- 'children' : children }
-
-def main():
- from clang.cindex import Index
- from pprint import pprint
-
- from optparse import OptionParser, OptionGroup
-
- global opts
-
- parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
- parser.add_option("", "--show-ids", dest="showIDs",
- help="Don't compute cursor IDs (very slow)",
- default=False)
- parser.add_option("", "--max-depth", dest="maxDepth",
- help="Limit cursor expansion to depth N",
- metavar="N", type=int, default=None)
- parser.disable_interspersed_args()
- (opts, args) = parser.parse_args()
-
- if len(args) == 0:
- parser.error('invalid number arguments')
-
- index = Index.create()
- tu = index.parse(None, args)
- if not tu:
- parser.error("unable to load input")
-
- pprint(('diags', map(get_diag_info, tu.diagnostics)))
- pprint(('nodes', get_info(tu.cursor)))
-
-if __name__ == '__main__':
- main()
-
diff --git a/bindings/python/examples/cindex/cindex-includes.py b/bindings/python/examples/cindex/cindex-includes.py
deleted file mode 100644
index 17500227a349..000000000000
--- a/bindings/python/examples/cindex/cindex-includes.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-
-#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-"""
-A simple command line tool for dumping a Graphviz description (dot) that
-describes include dependencies.
-"""
-
-def main():
- import sys
- from clang.cindex import Index
-
- from optparse import OptionParser, OptionGroup
-
- parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
- parser.disable_interspersed_args()
- (opts, args) = parser.parse_args()
- if len(args) == 0:
- parser.error('invalid number arguments')
-
- # FIXME: Add an output file option
- out = sys.stdout
-
- index = Index.create()
- tu = index.parse(None, args)
- if not tu:
- parser.error("unable to load input")
-
- # A helper function for generating the node name.
- def name(f):
- if f:
- return "\"" + f.name + "\""
-
- # Generate the include graph
- out.write("digraph G {\n")
- for i in tu.get_includes():
- line = " ";
- if i.is_input_file:
- # Always write the input file as a node just in case it doesn't
- # actually include anything. This would generate a 1 node graph.
- line += name(i.include)
- else:
- line += '%s->%s' % (name(i.source), name(i.include))
- line += "\n";
- out.write(line)
- out.write("}\n")
-
-if __name__ == '__main__':
- main()
-
diff --git a/bindings/python/tests/__init__.py b/bindings/python/tests/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/bindings/python/tests/__init__.py
+++ /dev/null
diff --git a/bindings/python/tests/cindex/INPUTS/compile_commands.json b/bindings/python/tests/cindex/INPUTS/compile_commands.json
deleted file mode 100644
index 944150bf7ba6..000000000000
--- a/bindings/python/tests/cindex/INPUTS/compile_commands.json
+++ /dev/null
@@ -1,17 +0,0 @@
-[
-{
- "directory": "/home/john.doe/MyProject",
- "command": "clang++ -o project.o -c /home/john.doe/MyProject/project.cpp",
- "file": "/home/john.doe/MyProject/project.cpp"
-},
-{
- "directory": "/home/john.doe/MyProjectA",
- "command": "clang++ -o project2.o -c /home/john.doe/MyProject/project2.cpp",
- "file": "/home/john.doe/MyProject/project2.cpp"
-},
-{
- "directory": "/home/john.doe/MyProjectB",
- "command": "clang++ -DFEATURE=1 -o project2-feature.o -c /home/john.doe/MyProject/project2.cpp",
- "file": "/home/john.doe/MyProject/project2.cpp"
-}
-]
diff --git a/bindings/python/tests/cindex/INPUTS/header1.h b/bindings/python/tests/cindex/INPUTS/header1.h
deleted file mode 100644
index b4eacbee3754..000000000000
--- a/bindings/python/tests/cindex/INPUTS/header1.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef HEADER1
-#define HEADER1
-
-#include "header3.h"
-
-#endif
diff --git a/bindings/python/tests/cindex/INPUTS/header2.h b/bindings/python/tests/cindex/INPUTS/header2.h
deleted file mode 100644
index c4eddc0c5620..000000000000
--- a/bindings/python/tests/cindex/INPUTS/header2.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef HEADER2
-#define HEADER2
-
-#include "header3.h"
-
-#endif
diff --git a/bindings/python/tests/cindex/INPUTS/header3.h b/bindings/python/tests/cindex/INPUTS/header3.h
deleted file mode 100644
index 6dca764860e1..000000000000
--- a/bindings/python/tests/cindex/INPUTS/header3.h
+++ /dev/null
@@ -1,3 +0,0 @@
-// Not a guarded header!
-
-void f();
diff --git a/bindings/python/tests/cindex/INPUTS/hello.cpp b/bindings/python/tests/cindex/INPUTS/hello.cpp
deleted file mode 100644
index 7ef086e56b2c..000000000000
--- a/bindings/python/tests/cindex/INPUTS/hello.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "stdio.h"
-
-int main(int argc, char* argv[]) {
- printf("hello world\n");
- return 0;
-}
diff --git a/bindings/python/tests/cindex/INPUTS/include.cpp b/bindings/python/tests/cindex/INPUTS/include.cpp
deleted file mode 100644
index 60cfdaae4d09..000000000000
--- a/bindings/python/tests/cindex/INPUTS/include.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "header1.h"
-#include "header2.h"
-#include "header1.h"
-
-int main() { }
diff --git a/bindings/python/tests/cindex/INPUTS/parse_arguments.c b/bindings/python/tests/cindex/INPUTS/parse_arguments.c
deleted file mode 100644
index 7196486c78a1..000000000000
--- a/bindings/python/tests/cindex/INPUTS/parse_arguments.c
+++ /dev/null
@@ -1,2 +0,0 @@
-int DECL_ONE = 1;
-int DECL_TWO = 2;
diff --git a/bindings/python/tests/cindex/__init__.py b/bindings/python/tests/cindex/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/bindings/python/tests/cindex/__init__.py
+++ /dev/null
diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py
deleted file mode 100644
index d0f580ea9f47..000000000000
--- a/bindings/python/tests/cindex/test_cdb.py
+++ /dev/null
@@ -1,89 +0,0 @@
-from clang.cindex import CompilationDatabase
-from clang.cindex import CompilationDatabaseError
-from clang.cindex import CompileCommands
-from clang.cindex import CompileCommand
-import os
-import gc
-
-kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
-
-def test_create_fail():
- """Check we fail loading a database with an assertion"""
- path = os.path.dirname(__file__)
- try:
- cdb = CompilationDatabase.fromDirectory(path)
- except CompilationDatabaseError as e:
- assert e.cdb_error == CompilationDatabaseError.ERROR_CANNOTLOADDATABASE
- else:
- assert False
-
-def test_create():
- """Check we can load a compilation database"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
-
-def test_lookup_fail():
- """Check file lookup failure"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- assert cdb.getCompileCommands('file_do_not_exist.cpp') == None
-
-def test_lookup_succeed():
- """Check we get some results if the file exists in the db"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
- assert len(cmds) != 0
-
-def test_1_compilecommand():
- """Check file with single compile command"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
- assert len(cmds) == 1
- assert cmds[0].directory == '/home/john.doe/MyProject'
- expected = [ 'clang++', '-o', 'project.o', '-c',
- '/home/john.doe/MyProject/project.cpp']
- for arg, exp in zip(cmds[0].arguments, expected):
- assert arg == exp
-
-def test_2_compilecommand():
- """Check file with 2 compile commands"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp')
- assert len(cmds) == 2
- expected = [
- { 'wd': '/home/john.doe/MyProjectA',
- 'line': ['clang++', '-o', 'project2.o', '-c',
- '/home/john.doe/MyProject/project2.cpp']},
- { 'wd': '/home/john.doe/MyProjectB',
- 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c',
- '/home/john.doe/MyProject/project2.cpp']}
- ]
- for i in range(len(cmds)):
- assert cmds[i].directory == expected[i]['wd']
- for arg, exp in zip(cmds[i].arguments, expected[i]['line']):
- assert arg == exp
-
-def test_compilecommand_iterator_stops():
- """Check that iterator stops after the correct number of elements"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- count = 0
- for cmd in cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp'):
- count += 1
- assert count <= 2
-
-def test_compilationDB_references():
- """Ensure CompilationsCommands are independent of the database"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
- del cdb
- gc.collect()
- workingdir = cmds[0].directory
-
-def test_compilationCommands_references():
- """Ensure CompilationsCommand keeps a reference to CompilationCommands"""
- cdb = CompilationDatabase.fromDirectory(kInputsDir)
- cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
- del cdb
- cmd0 = cmds[0]
- del cmds
- gc.collect()
- workingdir = cmd0.directory
-
diff --git a/bindings/python/tests/cindex/test_code_completion.py b/bindings/python/tests/cindex/test_code_completion.py
deleted file mode 100644
index 357d50db5131..000000000000
--- a/bindings/python/tests/cindex/test_code_completion.py
+++ /dev/null
@@ -1,75 +0,0 @@
-from clang.cindex import TranslationUnit
-
-def check_completion_results(cr, expected):
- assert cr is not None
- assert len(cr.diagnostics) == 0
-
- completions = [str(c) for c in cr.results]
-
- for c in expected:
- assert c in completions
-
-def test_code_complete():
- files = [('fake.c', """
-/// Aaa.
-int test1;
-
-/// Bbb.
-void test2(void);
-
-void f() {
-
-}
-""")]
-
- tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files,
- options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
-
- cr = tu.codeComplete('fake.c', 9, 1, unsaved_files=files, include_brief_comments=True)
-
- expected = [
- "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
- "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
- "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None"
- ]
- check_completion_results(cr, expected)
-
-def test_code_complete_availability():
- files = [('fake.cpp', """
-class P {
-protected:
- int member;
-};
-
-class Q : public P {
-public:
- using P::member;
-};
-
-void f(P x, Q y) {
- x.; // member is inaccessible
- y.; // member is accessible
-}
-""")]
-
- tu = TranslationUnit.from_source('fake.cpp', ['-std=c++98'], unsaved_files=files)
-
- cr = tu.codeComplete('fake.cpp', 12, 5, unsaved_files=files)
-
- expected = [
- "{'const', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
- "{'volatile', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
- "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
- "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None",
- "{'Q', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None"
- ]
- check_completion_results(cr, expected)
-
- cr = tu.codeComplete('fake.cpp', 13, 5, unsaved_files=files)
- expected = [
- "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None",
- "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 34 || Availability: Available || Brief comment: None",
- "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None",
- "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 34 || Availability: Available || Brief comment: None"
- ]
- check_completion_results(cr, expected)
diff --git a/bindings/python/tests/cindex/test_comment.py b/bindings/python/tests/cindex/test_comment.py
deleted file mode 100644
index d8f3129ac51e..000000000000
--- a/bindings/python/tests/cindex/test_comment.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from clang.cindex import TranslationUnit
-from tests.cindex.util import get_cursor
-
-def test_comment():
- files = [('fake.c', """
-/// Aaa.
-int test1;
-
-/// Bbb.
-/// x
-void test2(void);
-
-void f() {
-
-}
-""")]
- # make a comment-aware TU
- tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files,
- options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
- test1 = get_cursor(tu, 'test1')
- assert test1 is not None, "Could not find test1."
- assert test1.type.is_pod()
- raw = test1.raw_comment
- brief = test1.brief_comment
- assert raw == """/// Aaa."""
- assert brief == """Aaa."""
-
- test2 = get_cursor(tu, 'test2')
- raw = test2.raw_comment
- brief = test2.brief_comment
- assert raw == """/// Bbb.\n/// x"""
- assert brief == """Bbb. x"""
-
- f = get_cursor(tu, 'f')
- raw = f.raw_comment
- brief = f.brief_comment
- assert raw is None
- assert brief is None
-
-
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
deleted file mode 100644
index a27525cfe553..000000000000
--- a/bindings/python/tests/cindex/test_cursor.py
+++ /dev/null
@@ -1,261 +0,0 @@
-import gc
-
-from clang.cindex import CursorKind
-from clang.cindex import TranslationUnit
-from clang.cindex import TypeKind
-from .util import get_cursor
-from .util import get_cursors
-from .util import get_tu
-
-kInput = """\
-// FIXME: Find nicer way to drop builtins and other cruft.
-int start_decl;
-
-struct s0 {
- int a;
- int b;
-};
-
-struct s1;
-
-void f0(int a0, int a1) {
- int l0, l1;
-
- if (a0)
- return;
-
- for (;;) {
- break;
- }
-}
-"""
-
-def test_get_children():
- tu = get_tu(kInput)
-
- # Skip until past start_decl.
- it = tu.cursor.get_children()
- while it.next().spelling != 'start_decl':
- pass
-
- tu_nodes = list(it)
-
- assert len(tu_nodes) == 3
- for cursor in tu_nodes:
- assert cursor.translation_unit is not None
-
- assert tu_nodes[0] != tu_nodes[1]
- assert tu_nodes[0].kind == CursorKind.STRUCT_DECL
- assert tu_nodes[0].spelling == 's0'
- assert tu_nodes[0].is_definition() == True
- assert tu_nodes[0].location.file.name == 't.c'
- assert tu_nodes[0].location.line == 4
- assert tu_nodes[0].location.column == 8
- assert tu_nodes[0].hash > 0
- assert tu_nodes[0].translation_unit is not None
-
- s0_nodes = list(tu_nodes[0].get_children())
- assert len(s0_nodes) == 2
- assert s0_nodes[0].kind == CursorKind.FIELD_DECL
- assert s0_nodes[0].spelling == 'a'
- assert s0_nodes[0].type.kind == TypeKind.INT
- assert s0_nodes[1].kind == CursorKind.FIELD_DECL
- assert s0_nodes[1].spelling == 'b'
- assert s0_nodes[1].type.kind == TypeKind.INT
-
- assert tu_nodes[1].kind == CursorKind.STRUCT_DECL
- assert tu_nodes[1].spelling == 's1'
- assert tu_nodes[1].displayname == 's1'
- assert tu_nodes[1].is_definition() == False
-
- assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL
- assert tu_nodes[2].spelling == 'f0'
- assert tu_nodes[2].displayname == 'f0(int, int)'
- assert tu_nodes[2].is_definition() == True
-
-def test_references():
- """Ensure that references to TranslationUnit are kept."""
- tu = get_tu('int x;')
- cursors = list(tu.cursor.get_children())
- assert len(cursors) > 0
-
- cursor = cursors[0]
- assert isinstance(cursor.translation_unit, TranslationUnit)
-
- # Delete reference to TU and perform a full GC.
- del tu
- gc.collect()
- assert isinstance(cursor.translation_unit, TranslationUnit)
-
- # If the TU was destroyed, this should cause a segfault.
- parent = cursor.semantic_parent
-
-def test_canonical():
- source = 'struct X; struct X; struct X { int member; };'
- tu = get_tu(source)
-
- cursors = []
- for cursor in tu.cursor.get_children():
- if cursor.spelling == 'X':
- cursors.append(cursor)
-
- assert len(cursors) == 3
- assert cursors[1].canonical == cursors[2].canonical
-
-def test_is_static_method():
- """Ensure Cursor.is_static_method works."""
-
- source = 'class X { static void foo(); void bar(); };'
- tu = get_tu(source, lang='cpp')
-
- cls = get_cursor(tu, 'X')
- foo = get_cursor(tu, 'foo')
- bar = get_cursor(tu, 'bar')
- assert cls is not None
- assert foo is not None
- assert bar is not None
-
- assert foo.is_static_method()
- assert not bar.is_static_method()
-
-def test_underlying_type():
- tu = get_tu('typedef int foo;')
- typedef = get_cursor(tu, 'foo')
- assert typedef is not None
-
- assert typedef.kind.is_declaration()
- underlying = typedef.underlying_typedef_type
- assert underlying.kind == TypeKind.INT
-
-kParentTest = """\
- class C {
- void f();
- }
-
- void C::f() { }
- """
-def test_semantic_parent():
- tu = get_tu(kParentTest, 'cpp')
- curs = get_cursors(tu, 'f')
- decl = get_cursor(tu, 'C')
- assert(len(curs) == 2)
- assert(curs[0].semantic_parent == curs[1].semantic_parent)
- assert(curs[0].semantic_parent == decl)
-
-def test_lexical_parent():
- tu = get_tu(kParentTest, 'cpp')
- curs = get_cursors(tu, 'f')
- decl = get_cursor(tu, 'C')
- assert(len(curs) == 2)
- assert(curs[0].lexical_parent != curs[1].lexical_parent)
- assert(curs[0].lexical_parent == decl)
- assert(curs[1].lexical_parent == tu.cursor)
-
-def test_enum_type():
- tu = get_tu('enum TEST { FOO=1, BAR=2 };')
- enum = get_cursor(tu, 'TEST')
- assert enum is not None
-
- assert enum.kind == CursorKind.ENUM_DECL
- enum_type = enum.enum_type
- assert enum_type.kind == TypeKind.UINT
-
-def test_enum_type_cpp():
- tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp")
- enum = get_cursor(tu, 'TEST')
- assert enum is not None
-
- assert enum.kind == CursorKind.ENUM_DECL
- assert enum.enum_type.kind == TypeKind.LONGLONG
-
-def test_objc_type_encoding():
- tu = get_tu('int i;', lang='objc')
- i = get_cursor(tu, 'i')
-
- assert i is not None
- assert i.objc_type_encoding == 'i'
-
-def test_enum_values():
- tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};')
- enum = get_cursor(tu, 'TEST')
- assert enum is not None
-
- assert enum.kind == CursorKind.ENUM_DECL
-
- enum_constants = list(enum.get_children())
- assert len(enum_constants) == 3
-
- spam, egg, ham = enum_constants
-
- assert spam.kind == CursorKind.ENUM_CONSTANT_DECL
- assert spam.enum_value == 1
- assert egg.kind == CursorKind.ENUM_CONSTANT_DECL
- assert egg.enum_value == 2
- assert ham.kind == CursorKind.ENUM_CONSTANT_DECL
- assert ham.enum_value == 40
-
-def test_enum_values_cpp():
- tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp")
- enum = get_cursor(tu, 'TEST')
- assert enum is not None
-
- assert enum.kind == CursorKind.ENUM_DECL
-
- enum_constants = list(enum.get_children())
- assert len(enum_constants) == 2
-
- spam, ham = enum_constants
-
- assert spam.kind == CursorKind.ENUM_CONSTANT_DECL
- assert spam.enum_value == -1
- assert ham.kind == CursorKind.ENUM_CONSTANT_DECL
- assert ham.enum_value == 0x10000000000
-
-def test_annotation_attribute():
- tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));')
-
- foo = get_cursor(tu, 'foo')
- assert foo is not None
-
- for c in foo.get_children():
- if c.kind == CursorKind.ANNOTATE_ATTR:
- assert c.displayname == "here be annotation attribute"
- break
- else:
- assert False, "Couldn't find annotation"
-
-def test_result_type():
- tu = get_tu('int foo();')
- foo = get_cursor(tu, 'foo')
-
- assert foo is not None
- t = foo.result_type
- assert t.kind == TypeKind.INT
-
-def test_get_tokens():
- """Ensure we can map cursors back to tokens."""
- tu = get_tu('int foo(int i);')
- foo = get_cursor(tu, 'foo')
-
- tokens = list(foo.get_tokens())
- assert len(tokens) == 7
- assert tokens[0].spelling == 'int'
- assert tokens[1].spelling == 'foo'
-
-def test_get_arguments():
- tu = get_tu('void foo(int i, int j);')
- foo = get_cursor(tu, 'foo')
- arguments = list(foo.get_arguments())
-
- assert len(arguments) == 2
- assert arguments[0].spelling == "i"
- assert arguments[1].spelling == "j"
-
-def test_referenced():
- tu = get_tu('void foo(); void bar() { foo(); }')
- foo = get_cursor(tu, 'foo')
- bar = get_cursor(tu, 'bar')
- for c in bar.get_children():
- if c.kind == CursorKind.CALL_EXPR:
- assert c.referenced.spelling == foo.spelling
- break
diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py
deleted file mode 100644
index 8cabc512d4c5..000000000000
--- a/bindings/python/tests/cindex/test_cursor_kind.py
+++ /dev/null
@@ -1,47 +0,0 @@
-from clang.cindex import CursorKind
-
-def test_name():
- assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL'
-
-def test_get_all_kinds():
- kinds = CursorKind.get_all_kinds()
- assert CursorKind.UNEXPOSED_DECL in kinds
- assert CursorKind.TRANSLATION_UNIT in kinds
- assert CursorKind.VARIABLE_REF in kinds
- assert CursorKind.LAMBDA_EXPR in kinds
- assert CursorKind.OBJ_BOOL_LITERAL_EXPR in kinds
- assert CursorKind.OBJ_SELF_EXPR in kinds
- assert CursorKind.MS_ASM_STMT in kinds
- assert CursorKind.MODULE_IMPORT_DECL in kinds
-
-def test_kind_groups():
- """Check that every kind classifies to exactly one group."""
-
- assert CursorKind.UNEXPOSED_DECL.is_declaration()
- assert CursorKind.TYPE_REF.is_reference()
- assert CursorKind.DECL_REF_EXPR.is_expression()
- assert CursorKind.UNEXPOSED_STMT.is_statement()
- assert CursorKind.INVALID_FILE.is_invalid()
-
- assert CursorKind.TRANSLATION_UNIT.is_translation_unit()
- assert not CursorKind.TYPE_REF.is_translation_unit()
-
- assert CursorKind.PREPROCESSING_DIRECTIVE.is_preprocessing()
- assert not CursorKind.TYPE_REF.is_preprocessing()
-
- assert CursorKind.UNEXPOSED_DECL.is_unexposed()
- assert not CursorKind.TYPE_REF.is_unexposed()
-
- for k in CursorKind.get_all_kinds():
- group = [n for n in ('is_declaration', 'is_reference', 'is_expression',
- 'is_statement', 'is_invalid', 'is_attribute')
- if getattr(k, n)()]
-
- if k in ( CursorKind.TRANSLATION_UNIT,
- CursorKind.MACRO_DEFINITION,
- CursorKind.MACRO_INSTANTIATION,
- CursorKind.INCLUSION_DIRECTIVE,
- CursorKind.PREPROCESSING_DIRECTIVE):
- assert len(group) == 0
- else:
- assert len(group) == 1
diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py
deleted file mode 100644
index 48ab6176fd1d..000000000000
--- a/bindings/python/tests/cindex/test_diagnostics.py
+++ /dev/null
@@ -1,82 +0,0 @@
-from clang.cindex import *
-from .util import get_tu
-
-# FIXME: We need support for invalid translation units to test better.
-
-def test_diagnostic_warning():
- tu = get_tu('int f0() {}\n')
- assert len(tu.diagnostics) == 1
- assert tu.diagnostics[0].severity == Diagnostic.Warning
- assert tu.diagnostics[0].location.line == 1
- assert tu.diagnostics[0].location.column == 11
- assert (tu.diagnostics[0].spelling ==
- 'control reaches end of non-void function')
-
-def test_diagnostic_note():
- # FIXME: We aren't getting notes here for some reason.
- tu = get_tu('#define A x\nvoid *A = 1;\n')
- assert len(tu.diagnostics) == 1
- assert tu.diagnostics[0].severity == Diagnostic.Warning
- assert tu.diagnostics[0].location.line == 2
- assert tu.diagnostics[0].location.column == 7
- assert 'incompatible' in tu.diagnostics[0].spelling
-# assert tu.diagnostics[1].severity == Diagnostic.Note
-# assert tu.diagnostics[1].location.line == 1
-# assert tu.diagnostics[1].location.column == 11
-# assert tu.diagnostics[1].spelling == 'instantiated from'
-
-def test_diagnostic_fixit():
- tu = get_tu('struct { int f0; } x = { f0 : 1 };')
- assert len(tu.diagnostics) == 1
- assert tu.diagnostics[0].severity == Diagnostic.Warning
- assert tu.diagnostics[0].location.line == 1
- assert tu.diagnostics[0].location.column == 26
- assert tu.diagnostics[0].spelling.startswith('use of GNU old-style')
- assert len(tu.diagnostics[0].fixits) == 1
- assert tu.diagnostics[0].fixits[0].range.start.line == 1
- assert tu.diagnostics[0].fixits[0].range.start.column == 26
- assert tu.diagnostics[0].fixits[0].range.end.line == 1
- assert tu.diagnostics[0].fixits[0].range.end.column == 30
- assert tu.diagnostics[0].fixits[0].value == '.f0 = '
-
-def test_diagnostic_range():
- tu = get_tu('void f() { int i = "a" + 1; }')
- assert len(tu.diagnostics) == 1
- assert tu.diagnostics[0].severity == Diagnostic.Warning
- assert tu.diagnostics[0].location.line == 1
- assert tu.diagnostics[0].location.column == 16
- assert tu.diagnostics[0].spelling.startswith('incompatible pointer to')
- assert len(tu.diagnostics[0].fixits) == 0
- assert len(tu.diagnostics[0].ranges) == 1
- assert tu.diagnostics[0].ranges[0].start.line == 1
- assert tu.diagnostics[0].ranges[0].start.column == 20
- assert tu.diagnostics[0].ranges[0].end.line == 1
- assert tu.diagnostics[0].ranges[0].end.column == 27
- try:
- tu.diagnostics[0].ranges[1].start.line
- except IndexError:
- assert True
- else:
- assert False
-
-def test_diagnostic_category():
- """Ensure that category properties work."""
- tu = get_tu('int f(int i) { return 7; }', all_warnings=True)
- assert len(tu.diagnostics) == 1
- d = tu.diagnostics[0]
-
- assert d.severity == Diagnostic.Warning
- assert d.location.line == 1
- assert d.location.column == 11
-
- assert d.category_number == 2
- assert d.category_name == 'Semantic Issue'
-
-def test_diagnostic_option():
- """Ensure that category option properties work."""
- tu = get_tu('int f(int i) { return 7; }', all_warnings=True)
- assert len(tu.diagnostics) == 1
- d = tu.diagnostics[0]
-
- assert d.option == '-Wunused-parameter'
- assert d.disable_option == '-Wno-unused-parameter'
diff --git a/bindings/python/tests/cindex/test_file.py b/bindings/python/tests/cindex/test_file.py
deleted file mode 100644
index 146e8c570528..000000000000
--- a/bindings/python/tests/cindex/test_file.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from clang.cindex import Index, File
-
-def test_file():
- index = Index.create()
- tu = index.parse('t.c', unsaved_files = [('t.c', "")])
- file = File.from_name(tu, "t.c")
- assert str(file) == "t.c"
- assert file.name == "t.c"
- assert repr(file) == "<File: t.c>"
diff --git a/bindings/python/tests/cindex/test_index.py b/bindings/python/tests/cindex/test_index.py
deleted file mode 100644
index dc173f04d218..000000000000
--- a/bindings/python/tests/cindex/test_index.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from clang.cindex import *
-import os
-
-kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
-
-def test_create():
- index = Index.create()
-
-# FIXME: test Index.read
-
-def test_parse():
- index = Index.create()
- assert isinstance(index, Index)
- tu = index.parse(os.path.join(kInputsDir, 'hello.cpp'))
- assert isinstance(tu, TranslationUnit)
diff --git a/bindings/python/tests/cindex/test_location.py b/bindings/python/tests/cindex/test_location.py
deleted file mode 100644
index 9e9ef487af18..000000000000
--- a/bindings/python/tests/cindex/test_location.py
+++ /dev/null
@@ -1,95 +0,0 @@
-from clang.cindex import Cursor
-from clang.cindex import File
-from clang.cindex import SourceLocation
-from clang.cindex import SourceRange
-from .util import get_cursor
-from .util import get_tu
-
-baseInput="int one;\nint two;\n"
-
-def assert_location(loc, line, column, offset):
- assert loc.line == line
- assert loc.column == column
- assert loc.offset == offset
-
-def test_location():
- tu = get_tu(baseInput)
- one = get_cursor(tu, 'one')
- two = get_cursor(tu, 'two')
-
- assert one is not None
- assert two is not None
-
- assert_location(one.location,line=1,column=5,offset=4)
- assert_location(two.location,line=2,column=5,offset=13)
-
- # adding a linebreak at top should keep columns same
- tu = get_tu('\n' + baseInput)
- one = get_cursor(tu, 'one')
- two = get_cursor(tu, 'two')
-
- assert one is not None
- assert two is not None
-
- assert_location(one.location,line=2,column=5,offset=5)
- assert_location(two.location,line=3,column=5,offset=14)
-
- # adding a space should affect column on first line only
- tu = get_tu(' ' + baseInput)
- one = get_cursor(tu, 'one')
- two = get_cursor(tu, 'two')
-
- assert_location(one.location,line=1,column=6,offset=5)
- assert_location(two.location,line=2,column=5,offset=14)
-
- # define the expected location ourselves and see if it matches
- # the returned location
- tu = get_tu(baseInput)
-
- file = File.from_name(tu, 't.c')
- location = SourceLocation.from_position(tu, file, 1, 5)
- cursor = Cursor.from_location(tu, location)
-
- one = get_cursor(tu, 'one')
- assert one is not None
- assert one == cursor
-
- # Ensure locations referring to the same entity are equivalent.
- location2 = SourceLocation.from_position(tu, file, 1, 5)
- assert location == location2
- location3 = SourceLocation.from_position(tu, file, 1, 4)
- assert location2 != location3
-
- offset_location = SourceLocation.from_offset(tu, file, 5)
- cursor = Cursor.from_location(tu, offset_location)
- verified = False
- for n in [n for n in tu.cursor.get_children() if n.spelling == 'one']:
- assert n == cursor
- verified = True
-
- assert verified
-
-def test_extent():
- tu = get_tu(baseInput)
- one = get_cursor(tu, 'one')
- two = get_cursor(tu, 'two')
-
- assert_location(one.extent.start,line=1,column=1,offset=0)
- assert_location(one.extent.end,line=1,column=8,offset=7)
- assert baseInput[one.extent.start.offset:one.extent.end.offset] == "int one"
-
- assert_location(two.extent.start,line=2,column=1,offset=9)
- assert_location(two.extent.end,line=2,column=8,offset=16)
- assert baseInput[two.extent.start.offset:two.extent.end.offset] == "int two"
-
- file = File.from_name(tu, 't.c')
- location1 = SourceLocation.from_position(tu, file, 1, 1)
- location2 = SourceLocation.from_position(tu, file, 1, 8)
-
- range1 = SourceRange.from_locations(location1, location2)
- range2 = SourceRange.from_locations(location1, location2)
- assert range1 == range2
-
- location3 = SourceLocation.from_position(tu, file, 1, 6)
- range3 = SourceRange.from_locations(location1, location3)
- assert range1 != range3
diff --git a/bindings/python/tests/cindex/test_token_kind.py b/bindings/python/tests/cindex/test_token_kind.py
deleted file mode 100644
index 62ec63e0ad58..000000000000
--- a/bindings/python/tests/cindex/test_token_kind.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from clang.cindex import TokenKind
-from nose.tools import eq_
-from nose.tools import ok_
-from nose.tools import raises
-
-def test_constructor():
- """Ensure TokenKind constructor works as expected."""
-
- t = TokenKind(5, 'foo')
-
- eq_(t.value, 5)
- eq_(t.name, 'foo')
-
-@raises(ValueError)
-def test_bad_register():
- """Ensure a duplicate value is rejected for registration."""
-
- TokenKind.register(2, 'foo')
-
-@raises(ValueError)
-def test_unknown_value():
- """Ensure trying to fetch an unknown value raises."""
-
- TokenKind.from_value(-1)
-
-def test_registration():
- """Ensure that items registered appear as class attributes."""
- ok_(hasattr(TokenKind, 'LITERAL'))
- literal = TokenKind.LITERAL
-
- ok_(isinstance(literal, TokenKind))
-
-def test_from_value():
- """Ensure registered values can be obtained from from_value()."""
- t = TokenKind.from_value(3)
- ok_(isinstance(t, TokenKind))
- eq_(t, TokenKind.LITERAL)
-
-def test_repr():
- """Ensure repr() works."""
-
- r = repr(TokenKind.LITERAL)
- eq_(r, 'TokenKind.LITERAL')
diff --git a/bindings/python/tests/cindex/test_tokens.py b/bindings/python/tests/cindex/test_tokens.py
deleted file mode 100644
index 70748429094a..000000000000
--- a/bindings/python/tests/cindex/test_tokens.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from clang.cindex import CursorKind
-from clang.cindex import Index
-from clang.cindex import SourceLocation
-from clang.cindex import SourceRange
-from clang.cindex import TokenKind
-from nose.tools import eq_
-from nose.tools import ok_
-
-from .util import get_tu
-
-def test_token_to_cursor():
- """Ensure we can obtain a Cursor from a Token instance."""
- tu = get_tu('int i = 5;')
- r = tu.get_extent('t.c', (0, 9))
- tokens = list(tu.get_tokens(extent=r))
-
- assert len(tokens) == 5
- assert tokens[1].spelling == 'i'
- assert tokens[1].kind == TokenKind.IDENTIFIER
-
- cursor = tokens[1].cursor
- assert cursor.kind == CursorKind.VAR_DECL
- assert tokens[1].cursor == tokens[2].cursor
-
-def test_token_location():
- """Ensure Token.location works."""
-
- tu = get_tu('int foo = 10;')
- r = tu.get_extent('t.c', (0, 11))
-
- tokens = list(tu.get_tokens(extent=r))
- eq_(len(tokens), 4)
-
- loc = tokens[1].location
- ok_(isinstance(loc, SourceLocation))
- eq_(loc.line, 1)
- eq_(loc.column, 5)
- eq_(loc.offset, 4)
-
-def test_token_extent():
- """Ensure Token.extent works."""
- tu = get_tu('int foo = 10;')
- r = tu.get_extent('t.c', (0, 11))
-
- tokens = list(tu.get_tokens(extent=r))
- eq_(len(tokens), 4)
-
- extent = tokens[1].extent
- ok_(isinstance(extent, SourceRange))
-
- eq_(extent.start.offset, 4)
- eq_(extent.end.offset, 7)
diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py
deleted file mode 100644
index f77998e52457..000000000000
--- a/bindings/python/tests/cindex/test_translation_unit.py
+++ /dev/null
@@ -1,258 +0,0 @@
-import gc
-import os
-
-from clang.cindex import CursorKind
-from clang.cindex import Cursor
-from clang.cindex import File
-from clang.cindex import Index
-from clang.cindex import SourceLocation
-from clang.cindex import SourceRange
-from clang.cindex import TranslationUnitSaveError
-from clang.cindex import TranslationUnitLoadError
-from clang.cindex import TranslationUnit
-from .util import get_cursor
-from .util import get_tu
-
-kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
-
-def test_spelling():
- path = os.path.join(kInputsDir, 'hello.cpp')
- tu = TranslationUnit.from_source(path)
- assert tu.spelling == path
-
-def test_cursor():
- path = os.path.join(kInputsDir, 'hello.cpp')
- tu = get_tu(path)
- c = tu.cursor
- assert isinstance(c, Cursor)
- assert c.kind is CursorKind.TRANSLATION_UNIT
-
-def test_parse_arguments():
- path = os.path.join(kInputsDir, 'parse_arguments.c')
- tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
- spellings = [c.spelling for c in tu.cursor.get_children()]
- assert spellings[-2] == 'hello'
- assert spellings[-1] == 'hi'
-
-def test_reparse_arguments():
- path = os.path.join(kInputsDir, 'parse_arguments.c')
- tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
- tu.reparse()
- spellings = [c.spelling for c in tu.cursor.get_children()]
- assert spellings[-2] == 'hello'
- assert spellings[-1] == 'hi'
-
-def test_unsaved_files():
- tu = TranslationUnit.from_source('fake.c', ['-I./'], unsaved_files = [
- ('fake.c', """
-#include "fake.h"
-int x;
-int SOME_DEFINE;
-"""),
- ('./fake.h', """
-#define SOME_DEFINE y
-""")
- ])
- spellings = [c.spelling for c in tu.cursor.get_children()]
- assert spellings[-2] == 'x'
- assert spellings[-1] == 'y'
-
-def test_unsaved_files_2():
- import StringIO
- tu = TranslationUnit.from_source('fake.c', unsaved_files = [
- ('fake.c', StringIO.StringIO('int x;'))])
- spellings = [c.spelling for c in tu.cursor.get_children()]
- assert spellings[-1] == 'x'
-
-def normpaths_equal(path1, path2):
- """ Compares two paths for equality after normalizing them with
- os.path.normpath
- """
- return os.path.normpath(path1) == os.path.normpath(path2)
-
-def test_includes():
- def eq(expected, actual):
- if not actual.is_input_file:
- return normpaths_equal(expected[0], actual.source.name) and \
- normpaths_equal(expected[1], actual.include.name)
- else:
- return normpaths_equal(expected[1], actual.include.name)
-
- src = os.path.join(kInputsDir, 'include.cpp')
- h1 = os.path.join(kInputsDir, "header1.h")
- h2 = os.path.join(kInputsDir, "header2.h")
- h3 = os.path.join(kInputsDir, "header3.h")
- inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)]
-
- tu = TranslationUnit.from_source(src)
- for i in zip(inc, tu.get_includes()):
- assert eq(i[0], i[1])
-
-def save_tu(tu):
- """Convenience API to save a TranslationUnit to a file.
-
- Returns the filename it was saved to.
- """
-
- # FIXME Generate a temp file path using system APIs.
- base = 'TEMP_FOR_TRANSLATIONUNIT_SAVE.c'
- path = os.path.join(kInputsDir, base)
-
- # Just in case.
- if os.path.exists(path):
- os.unlink(path)
-
- tu.save(path)
-
- return path
-
-def test_save():
- """Ensure TranslationUnit.save() works."""
-
- tu = get_tu('int foo();')
-
- path = save_tu(tu)
- assert os.path.exists(path)
- assert os.path.getsize(path) > 0
- os.unlink(path)
-
-def test_save_translation_errors():
- """Ensure that saving to an invalid directory raises."""
-
- tu = get_tu('int foo();')
-
- path = '/does/not/exist/llvm-test.ast'
- assert not os.path.exists(os.path.dirname(path))
-
- try:
- tu.save(path)
- assert False
- except TranslationUnitSaveError as ex:
- expected = TranslationUnitSaveError.ERROR_UNKNOWN
- assert ex.save_error == expected
-
-def test_load():
- """Ensure TranslationUnits can be constructed from saved files."""
-
- tu = get_tu('int foo();')
- assert len(tu.diagnostics) == 0
- path = save_tu(tu)
-
- assert os.path.exists(path)
- assert os.path.getsize(path) > 0
-
- tu2 = TranslationUnit.from_ast_file(filename=path)
- assert len(tu2.diagnostics) == 0
-
- foo = get_cursor(tu2, 'foo')
- assert foo is not None
-
- # Just in case there is an open file descriptor somewhere.
- del tu2
-
- os.unlink(path)
-
-def test_index_parse():
- path = os.path.join(kInputsDir, 'hello.cpp')
- index = Index.create()
- tu = index.parse(path)
- assert isinstance(tu, TranslationUnit)
-
-def test_get_file():
- """Ensure tu.get_file() works appropriately."""
-
- tu = get_tu('int foo();')
-
- f = tu.get_file('t.c')
- assert isinstance(f, File)
- assert f.name == 't.c'
-
- try:
- f = tu.get_file('foobar.cpp')
- except:
- pass
- else:
- assert False
-
-def test_get_source_location():
- """Ensure tu.get_source_location() works."""
-
- tu = get_tu('int foo();')
-
- location = tu.get_location('t.c', 2)
- assert isinstance(location, SourceLocation)
- assert location.offset == 2
- assert location.file.name == 't.c'
-
- location = tu.get_location('t.c', (1, 3))
- assert isinstance(location, SourceLocation)
- assert location.line == 1
- assert location.column == 3
- assert location.file.name == 't.c'
-
-def test_get_source_range():
- """Ensure tu.get_source_range() works."""
-
- tu = get_tu('int foo();')
-
- r = tu.get_extent('t.c', (1,4))
- assert isinstance(r, SourceRange)
- assert r.start.offset == 1
- assert r.end.offset == 4
- assert r.start.file.name == 't.c'
- assert r.end.file.name == 't.c'
-
- r = tu.get_extent('t.c', ((1,2), (1,3)))
- assert isinstance(r, SourceRange)
- assert r.start.line == 1
- assert r.start.column == 2
- assert r.end.line == 1
- assert r.end.column == 3
- assert r.start.file.name == 't.c'
- assert r.end.file.name == 't.c'
-
- start = tu.get_location('t.c', 0)
- end = tu.get_location('t.c', 5)
-
- r = tu.get_extent('t.c', (start, end))
- assert isinstance(r, SourceRange)
- assert r.start.offset == 0
- assert r.end.offset == 5
- assert r.start.file.name == 't.c'
- assert r.end.file.name == 't.c'
-
-def test_get_tokens_gc():
- """Ensures get_tokens() works properly with garbage collection."""
-
- tu = get_tu('int foo();')
- r = tu.get_extent('t.c', (0, 10))
- tokens = list(tu.get_tokens(extent=r))
-
- assert tokens[0].spelling == 'int'
- gc.collect()
- assert tokens[0].spelling == 'int'
-
- del tokens[1]
- gc.collect()
- assert tokens[0].spelling == 'int'
-
- # May trigger segfault if we don't do our job properly.
- del tokens
- gc.collect()
- gc.collect() # Just in case.
-
-def test_fail_from_source():
- path = os.path.join(kInputsDir, 'non-existent.cpp')
- try:
- tu = TranslationUnit.from_source(path)
- except TranslationUnitLoadError:
- tu = None
- assert tu == None
-
-def test_fail_from_ast_file():
- path = os.path.join(kInputsDir, 'non-existent.ast')
- try:
- tu = TranslationUnit.from_ast_file(path)
- except TranslationUnitLoadError:
- tu = None
- assert tu == None
diff --git a/bindings/python/tests/cindex/test_type.py b/bindings/python/tests/cindex/test_type.py
deleted file mode 100644
index a02c06fe5a13..000000000000
--- a/bindings/python/tests/cindex/test_type.py
+++ /dev/null
@@ -1,397 +0,0 @@
-import gc
-
-from clang.cindex import CursorKind
-from clang.cindex import TranslationUnit
-from clang.cindex import TypeKind
-from nose.tools import raises
-from .util import get_cursor
-from .util import get_tu
-
-kInput = """\
-
-typedef int I;
-
-struct teststruct {
- int a;
- I b;
- long c;
- unsigned long d;
- signed long e;
- const int f;
- int *g;
- int ***h;
-};
-
-"""
-
-def test_a_struct():
- tu = get_tu(kInput)
-
- teststruct = get_cursor(tu, 'teststruct')
- assert teststruct is not None, "Could not find teststruct."
- fields = list(teststruct.get_children())
- assert all(x.kind == CursorKind.FIELD_DECL for x in fields)
- assert all(x.translation_unit is not None for x in fields)
-
- assert fields[0].spelling == 'a'
- assert not fields[0].type.is_const_qualified()
- assert fields[0].type.kind == TypeKind.INT
- assert fields[0].type.get_canonical().kind == TypeKind.INT
-
- assert fields[1].spelling == 'b'
- assert not fields[1].type.is_const_qualified()
- assert fields[1].type.kind == TypeKind.TYPEDEF
- assert fields[1].type.get_canonical().kind == TypeKind.INT
- assert fields[1].type.get_declaration().spelling == 'I'
-
- assert fields[2].spelling == 'c'
- assert not fields[2].type.is_const_qualified()
- assert fields[2].type.kind == TypeKind.LONG
- assert fields[2].type.get_canonical().kind == TypeKind.LONG
-
- assert fields[3].spelling == 'd'
- assert not fields[3].type.is_const_qualified()
- assert fields[3].type.kind == TypeKind.ULONG
- assert fields[3].type.get_canonical().kind == TypeKind.ULONG
-
- assert fields[4].spelling == 'e'
- assert not fields[4].type.is_const_qualified()
- assert fields[4].type.kind == TypeKind.LONG
- assert fields[4].type.get_canonical().kind == TypeKind.LONG
-
- assert fields[5].spelling == 'f'
- assert fields[5].type.is_const_qualified()
- assert fields[5].type.kind == TypeKind.INT
- assert fields[5].type.get_canonical().kind == TypeKind.INT
-
- assert fields[6].spelling == 'g'
- assert not fields[6].type.is_const_qualified()
- assert fields[6].type.kind == TypeKind.POINTER
- assert fields[6].type.get_pointee().kind == TypeKind.INT
-
- assert fields[7].spelling == 'h'
- assert not fields[7].type.is_const_qualified()
- assert fields[7].type.kind == TypeKind.POINTER
- assert fields[7].type.get_pointee().kind == TypeKind.POINTER
- assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER
- assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT
-
-def test_references():
- """Ensure that a Type maintains a reference to a TranslationUnit."""
-
- tu = get_tu('int x;')
- children = list(tu.cursor.get_children())
- assert len(children) > 0
-
- cursor = children[0]
- t = cursor.type
-
- assert isinstance(t.translation_unit, TranslationUnit)
-
- # Delete main TranslationUnit reference and force a GC.
- del tu
- gc.collect()
- assert isinstance(t.translation_unit, TranslationUnit)
-
- # If the TU was destroyed, this should cause a segfault.
- decl = t.get_declaration()
-
-constarrayInput="""
-struct teststruct {
- void *A[2];
-};
-"""
-def testConstantArray():
- tu = get_tu(constarrayInput)
-
- teststruct = get_cursor(tu, 'teststruct')
- assert teststruct is not None, "Didn't find teststruct??"
- fields = list(teststruct.get_children())
- assert fields[0].spelling == 'A'
- assert fields[0].type.kind == TypeKind.CONSTANTARRAY
- assert fields[0].type.get_array_element_type() is not None
- assert fields[0].type.get_array_element_type().kind == TypeKind.POINTER
- assert fields[0].type.get_array_size() == 2
-
-def test_equal():
- """Ensure equivalence operators work on Type."""
- source = 'int a; int b; void *v;'
- tu = get_tu(source)
-
- a = get_cursor(tu, 'a')
- b = get_cursor(tu, 'b')
- v = get_cursor(tu, 'v')
-
- assert a is not None
- assert b is not None
- assert v is not None
-
- assert a.type == b.type
- assert a.type != v.type
-
- assert a.type != None
- assert a.type != 'foo'
-
-def test_type_spelling():
- """Ensure Type.spelling works."""
- tu = get_tu('int c[5]; int i[]; int x; int v[x];')
- c = get_cursor(tu, 'c')
- i = get_cursor(tu, 'i')
- x = get_cursor(tu, 'x')
- v = get_cursor(tu, 'v')
- assert c is not None
- assert i is not None
- assert x is not None
- assert v is not None
- assert c.type.spelling == "int [5]"
- assert i.type.spelling == "int []"
- assert x.type.spelling == "int"
- assert v.type.spelling == "int [x]"
-
-def test_typekind_spelling():
- """Ensure TypeKind.spelling works."""
- tu = get_tu('int a;')
- a = get_cursor(tu, 'a')
-
- assert a is not None
- assert a.type.kind.spelling == 'Int'
-
-def test_function_argument_types():
- """Ensure that Type.argument_types() works as expected."""
- tu = get_tu('void f(int, int);')
- f = get_cursor(tu, 'f')
- assert f is not None
-
- args = f.type.argument_types()
- assert args is not None
- assert len(args) == 2
-
- t0 = args[0]
- assert t0 is not None
- assert t0.kind == TypeKind.INT
-
- t1 = args[1]
- assert t1 is not None
- assert t1.kind == TypeKind.INT
-
- args2 = list(args)
- assert len(args2) == 2
- assert t0 == args2[0]
- assert t1 == args2[1]
-
-@raises(TypeError)
-def test_argument_types_string_key():
- """Ensure that non-int keys raise a TypeError."""
- tu = get_tu('void f(int, int);')
- f = get_cursor(tu, 'f')
- assert f is not None
-
- args = f.type.argument_types()
- assert len(args) == 2
-
- args['foo']
-
-@raises(IndexError)
-def test_argument_types_negative_index():
- """Ensure that negative indexes on argument_types Raises an IndexError."""
- tu = get_tu('void f(int, int);')
- f = get_cursor(tu, 'f')
- args = f.type.argument_types()
-
- args[-1]
-
-@raises(IndexError)
-def test_argument_types_overflow_index():
- """Ensure that indexes beyond the length of Type.argument_types() raise."""
- tu = get_tu('void f(int, int);')
- f = get_cursor(tu, 'f')
- args = f.type.argument_types()
-
- args[2]
-
-@raises(Exception)
-def test_argument_types_invalid_type():
- """Ensure that obtaining argument_types on a Type without them raises."""
- tu = get_tu('int i;')
- i = get_cursor(tu, 'i')
- assert i is not None
-
- i.type.argument_types()
-
-def test_is_pod():
- """Ensure Type.is_pod() works."""
- tu = get_tu('int i; void f();')
- i = get_cursor(tu, 'i')
- f = get_cursor(tu, 'f')
-
- assert i is not None
- assert f is not None
-
- assert i.type.is_pod()
- assert not f.type.is_pod()
-
-def test_function_variadic():
- """Ensure Type.is_function_variadic works."""
-
- source ="""
-#include <stdarg.h>
-
-void foo(int a, ...);
-void bar(int a, int b);
-"""
-
- tu = get_tu(source)
- foo = get_cursor(tu, 'foo')
- bar = get_cursor(tu, 'bar')
-
- assert foo is not None
- assert bar is not None
-
- assert isinstance(foo.type.is_function_variadic(), bool)
- assert foo.type.is_function_variadic()
- assert not bar.type.is_function_variadic()
-
-def test_element_type():
- """Ensure Type.element_type works."""
- tu = get_tu('int c[5]; int i[]; int x; int v[x];')
- c = get_cursor(tu, 'c')
- i = get_cursor(tu, 'i')
- v = get_cursor(tu, 'v')
- assert c is not None
- assert i is not None
- assert v is not None
-
- assert c.type.kind == TypeKind.CONSTANTARRAY
- assert c.type.element_type.kind == TypeKind.INT
- assert i.type.kind == TypeKind.INCOMPLETEARRAY
- assert i.type.element_type.kind == TypeKind.INT
- assert v.type.kind == TypeKind.VARIABLEARRAY
- assert v.type.element_type.kind == TypeKind.INT
-
-@raises(Exception)
-def test_invalid_element_type():
- """Ensure Type.element_type raises if type doesn't have elements."""
- tu = get_tu('int i;')
- i = get_cursor(tu, 'i')
- assert i is not None
- i.element_type
-
-def test_element_count():
- """Ensure Type.element_count works."""
- tu = get_tu('int i[5]; int j;')
- i = get_cursor(tu, 'i')
- j = get_cursor(tu, 'j')
-
- assert i is not None
- assert j is not None
-
- assert i.type.element_count == 5
-
- try:
- j.type.element_count
- assert False
- except:
- assert True
-
-def test_is_volatile_qualified():
- """Ensure Type.is_volatile_qualified works."""
-
- tu = get_tu('volatile int i = 4; int j = 2;')
-
- i = get_cursor(tu, 'i')
- j = get_cursor(tu, 'j')
-
- assert i is not None
- assert j is not None
-
- assert isinstance(i.type.is_volatile_qualified(), bool)
- assert i.type.is_volatile_qualified()
- assert not j.type.is_volatile_qualified()
-
-def test_is_restrict_qualified():
- """Ensure Type.is_restrict_qualified works."""
-
- tu = get_tu('struct s { void * restrict i; void * j; };')
-
- i = get_cursor(tu, 'i')
- j = get_cursor(tu, 'j')
-
- assert i is not None
- assert j is not None
-
- assert isinstance(i.type.is_restrict_qualified(), bool)
- assert i.type.is_restrict_qualified()
- assert not j.type.is_restrict_qualified()
-
-def test_record_layout():
- """Ensure Cursor.type.get_size, Cursor.type.get_align and
- Cursor.type.get_offset works."""
-
- source ="""
-struct a {
- long a1;
- long a2:3;
- long a3:4;
- long long a4;
-};
-"""
- tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)),
- (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)),
- (['-target','i386-pc-win32'],(8,16,0,32,35,64)),
- (['-target','msp430-none-none'],(2,14,0,32,35,48))]
- for flags, values in tries:
- align,total,a1,a2,a3,a4 = values
-
- tu = get_tu(source, flags=flags)
- teststruct = get_cursor(tu, 'a')
- fields = list(teststruct.get_children())
-
- assert teststruct.type.get_align() == align
- assert teststruct.type.get_size() == total
- assert teststruct.type.get_offset(fields[0].spelling) == a1
- assert teststruct.type.get_offset(fields[1].spelling) == a2
- assert teststruct.type.get_offset(fields[2].spelling) == a3
- assert teststruct.type.get_offset(fields[3].spelling) == a4
- assert fields[0].is_bitfield() == False
- assert fields[1].is_bitfield() == True
- assert fields[1].get_bitfield_width() == 3
- assert fields[2].is_bitfield() == True
- assert fields[2].get_bitfield_width() == 4
- assert fields[3].is_bitfield() == False
-
-def test_offset():
- """Ensure Cursor.get_record_field_offset works in anonymous records"""
- source="""
-struct Test {
- struct {
- int bariton;
- union {
- int foo;
- };
- };
- int bar;
-};"""
- tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64)),
- (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64)),
- (['-target','i386-pc-win32'],(8,16,0,32,64)),
- (['-target','msp430-none-none'],(2,14,0,32,64))]
- for flags, values in tries:
- align,total,bariton,foo,bar = values
- tu = get_tu(source)
- teststruct = get_cursor(tu, 'Test')
- fields = list(teststruct.get_children())
- assert teststruct.type.get_offset("bariton") == bariton
- assert teststruct.type.get_offset("foo") == foo
- assert teststruct.type.get_offset("bar") == bar
-
-
-def test_decay():
- """Ensure decayed types are handled as the original type"""
-
- tu = get_tu("void foo(int a[]);")
- foo = get_cursor(tu, 'foo')
- a = foo.type.argument_types()[0]
-
- assert a.kind == TypeKind.INCOMPLETEARRAY
- assert a.element_type.kind == TypeKind.INT
- assert a.get_canonical().kind == TypeKind.INCOMPLETEARRAY
diff --git a/bindings/python/tests/cindex/util.py b/bindings/python/tests/cindex/util.py
deleted file mode 100644
index 8614b02ad258..000000000000
--- a/bindings/python/tests/cindex/util.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# This file provides common utility functions for the test suite.
-
-from clang.cindex import Cursor
-from clang.cindex import TranslationUnit
-
-def get_tu(source, lang='c', all_warnings=False, flags=[]):
- """Obtain a translation unit from source and language.
-
- By default, the translation unit is created from source file "t.<ext>"
- where <ext> is the default file extension for the specified language. By
- default it is C, so "t.c" is the default file name.
-
- Supported languages are {c, cpp, objc}.
-
- all_warnings is a convenience argument to enable all compiler warnings.
- """
- args = list(flags)
- name = 't.c'
- if lang == 'cpp':
- name = 't.cpp'
- args.append('-std=c++11')
- elif lang == 'objc':
- name = 't.m'
- elif lang != 'c':
- raise Exception('Unknown language: %s' % lang)
-
- if all_warnings:
- args += ['-Wall', '-Wextra']
-
- return TranslationUnit.from_source(name, args, unsaved_files=[(name,
- source)])
-
-def get_cursor(source, spelling):
- """Obtain a cursor from a source object.
-
- This provides a convenient search mechanism to find a cursor with specific
- spelling within a source. The first argument can be either a
- TranslationUnit or Cursor instance.
-
- If the cursor is not found, None is returned.
- """
- children = []
- if isinstance(source, Cursor):
- children = source.get_children()
- else:
- # Assume TU
- children = source.cursor.get_children()
-
- for cursor in children:
- if cursor.spelling == spelling:
- return cursor
-
- # Recurse into children.
- result = get_cursor(cursor, spelling)
- if result is not None:
- return result
-
- return None
-
-def get_cursors(source, spelling):
- """Obtain all cursors from a source object with a specific spelling.
-
- This provides a convenient search mechanism to find all cursors with specific
- spelling within a source. The first argument can be either a
- TranslationUnit or Cursor instance.
-
- If no cursors are found, an empty list is returned.
- """
- cursors = []
- children = []
- if isinstance(source, Cursor):
- children = source.get_children()
- else:
- # Assume TU
- children = source.cursor.get_children()
-
- for cursor in children:
- if cursor.spelling == spelling:
- cursors.append(cursor)
-
- # Recurse into children.
- cursors.extend(get_cursors(cursor, spelling))
-
- return cursors
-
-
-
-
-__all__ = [
- 'get_cursor',
- 'get_cursors',
- 'get_tu',
-]