Revert "Support for Python 3 in libclang python bindings"

This reverts commit 4464581bb63e9789e9ee231a8c8800be5f614743.

Memory access issues on Linux were reported by Mathieu Duponchelle and
discussed here: https://reviews.llvm.org/D26082.

llvm-svn: 291907
This commit is contained in:
Jonathan Coe 2017-01-13 16:06:59 +00:00
parent 8f5976ec00
commit 435aaeefe9
2 changed files with 56 additions and 97 deletions

View File

@ -64,7 +64,6 @@ call is efficient.
from ctypes import *
import collections
import sys
import clang.enumerations
@ -74,33 +73,6 @@ import clang.enumerations
# this by marshalling object arguments as void**.
c_object_p = POINTER(c_void_p)
if sys.version_info[0] > 2:
# Python 3 strings are unicode, translate them to/from utf8 for C-interop
# Python 3 replaces xrange with range, we want xrange behaviour
xrange = range
class c_string_p(c_char_p):
def __init__(self, p=None):
if type(p) == str:
p = p.encode("utf8")
super(c_char_p, self).__init__(p)
def __str__(self):
return str(self.value)
@property
def value(self):
if super(c_char_p, self).value is None:
return None
return super(c_char_p, self).value.decode("utf8")
@classmethod
def from_param(cls, param):
return cls(param)
else:
c_string_p = c_char_p
callbacks = {}
### Exception Classes ###
@ -175,7 +147,7 @@ class CachedProperty(object):
class _CXString(Structure):
"""Helper for transforming CXString results."""
_fields_ = [("spelling", c_string_p), ("free", c_int)]
_fields_ = [("spelling", c_char_p), ("free", c_int)]
def __del__(self):
conf.lib.clang_disposeString(self)
@ -357,7 +329,7 @@ class Diagnostic(object):
@property
def spelling(self):
return str(conf.lib.clang_getDiagnosticSpelling(self))
return conf.lib.clang_getDiagnosticSpelling(self)
@property
def ranges(self):
@ -386,8 +358,8 @@ class Diagnostic(object):
def __getitem__(self, key):
range = SourceRange()
value = str(conf.lib.clang_getDiagnosticFixIt(self.diag, key,
byref(range)))
value = conf.lib.clang_getDiagnosticFixIt(self.diag, key,
byref(range))
if len(value) == 0:
raise IndexError
@ -420,12 +392,12 @@ class Diagnostic(object):
@property
def category_name(self):
"""The string name of the category for this diagnostic."""
return str(conf.lib.clang_getDiagnosticCategoryText(self))
return conf.lib.clang_getDiagnosticCategoryText(self)
@property
def option(self):
"""The command-line option that enables this diagnostic."""
return str(conf.lib.clang_getDiagnosticOption(self, None))
return conf.lib.clang_getDiagnosticOption(self, None)
@property
def disable_option(self):
@ -433,7 +405,7 @@ class Diagnostic(object):
disable = _CXString()
conf.lib.clang_getDiagnosticOption(self, byref(disable))
return str(conf.lib.clang_getCString(disable))
return conf.lib.clang_getCString(disable)
def format(self, options=None):
"""
@ -582,8 +554,8 @@ class BaseEnumeration(object):
if value >= len(self.__class__._kinds):
self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1)
if self.__class__._kinds[value] is not None:
raise ValueError('{0} value {1} already loaded'.format(
str(self.__class__), value))
raise ValueError,'{0} value {1} already loaded'.format(
str(self.__class__), value)
self.value = value
self.__class__._kinds[value] = self
self.__class__._name_map = None
@ -600,12 +572,12 @@ class BaseEnumeration(object):
for key, value in self.__class__.__dict__.items():
if isinstance(value, self.__class__):
self._name_map[value] = key
return str(self._name_map[self])
return self._name_map[self]
@classmethod
def from_id(cls, id):
if id >= len(cls._kinds) or cls._kinds[id] is None:
raise ValueError('Unknown template argument kind %d' % id)
raise ValueError,'Unknown template argument kind %d' % id
return cls._kinds[id]
def __repr__(self):
@ -624,7 +596,7 @@ class CursorKind(BaseEnumeration):
@staticmethod
def get_all_kinds():
"""Return all CursorKind enumeration instances."""
return [x for x in CursorKind._kinds if x]
return filter(None, CursorKind._kinds)
def is_declaration(self):
"""Test if this is a declaration kind."""
@ -1457,9 +1429,9 @@ class Cursor(Structure):
def spelling(self):
"""Return the spelling of the entity pointed at by the cursor."""
if not hasattr(self, '_spelling'):
self._spelling = str(conf.lib.clang_getCursorSpelling(self))
self._spelling = conf.lib.clang_getCursorSpelling(self)
return str(self._spelling)
return self._spelling
@property
def displayname(self):
@ -1471,7 +1443,7 @@ class Cursor(Structure):
arguments of a class template specialization.
"""
if not hasattr(self, '_displayname'):
self._displayname = str(conf.lib.clang_getCursorDisplayName(self))
self._displayname = conf.lib.clang_getCursorDisplayName(self)
return self._displayname
@ -1479,7 +1451,7 @@ class Cursor(Structure):
def mangled_name(self):
"""Return the mangled name for the entity referenced by this cursor."""
if not hasattr(self, '_mangled_name'):
self._mangled_name = str(conf.lib.clang_Cursor_getMangling(self))
self._mangled_name = conf.lib.clang_Cursor_getMangling(self)
return self._mangled_name
@ -1618,7 +1590,7 @@ class Cursor(Structure):
self._objc_type_encoding = \
conf.lib.clang_getDeclObjCTypeEncoding(self)
return str(self._objc_type_encoding)
return self._objc_type_encoding
@property
def hash(self):
@ -1665,23 +1637,17 @@ class Cursor(Structure):
@property
def brief_comment(self):
"""Returns the brief comment text associated with that Cursor"""
r = conf.lib.clang_Cursor_getBriefCommentText(self)
if not r:
return None
return str(r)
return conf.lib.clang_Cursor_getBriefCommentText(self)
@property
def raw_comment(self):
"""Returns the raw comment text associated with that Cursor"""
r = conf.lib.clang_Cursor_getRawCommentText(self)
if not r:
return None
return str(r)
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 xrange(0, num_args):
for i in range(0, num_args):
yield conf.lib.clang_Cursor_getArgument(self, i)
def get_num_template_arguments(self):
@ -1811,7 +1777,7 @@ class StorageClass(object):
if value >= len(StorageClass._kinds):
StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1)
if StorageClass._kinds[value] is not None:
raise ValueError('StorageClass already loaded')
raise ValueError,'StorageClass already loaded'
self.value = value
StorageClass._kinds[value] = self
StorageClass._name_map = None
@ -1832,7 +1798,7 @@ class StorageClass(object):
@staticmethod
def from_id(id):
if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
raise ValueError('Unknown storage class %d' % id)
raise ValueError,'Unknown storage class %d' % id
return StorageClass._kinds[id]
def __repr__(self):
@ -1885,7 +1851,7 @@ class TypeKind(BaseEnumeration):
@property
def spelling(self):
"""Retrieve the spelling of this TypeKind."""
return str(conf.lib.clang_getTypeKindSpelling(self.value))
return conf.lib.clang_getTypeKindSpelling(self.value)
def __repr__(self):
return 'TypeKind.%s' % (self.name,)
@ -2161,7 +2127,7 @@ class Type(Structure):
"""
Retrieve the offset of a field in the record.
"""
return conf.lib.clang_Type_getOffsetOf(self, fieldname)
return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
def get_ref_qualifier(self):
"""
@ -2188,7 +2154,7 @@ class Type(Structure):
@property
def spelling(self):
"""Retrieve the spelling of this Type."""
return str(conf.lib.clang_getTypeSpelling(self))
return conf.lib.clang_getTypeSpelling(self)
def __eq__(self, other):
if type(other) != type(self):
@ -2220,7 +2186,7 @@ class ClangObject(object):
class _CXUnsavedFile(Structure):
"""Helper for passing unsaved file arguments."""
_fields_ = [("name", c_string_p), ("contents", c_string_p), ('length', c_ulong)]
_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
@ -2266,7 +2232,7 @@ class CompletionChunk:
self.__kindNumberCache = -1
def __repr__(self):
return "{'" + str(self.spelling) + "', " + str(self.kind) + "}"
return "{'" + self.spelling + "', " + str(self.kind) + "}"
@CachedProperty
def spelling(self):
@ -2575,9 +2541,7 @@ class TranslationUnit(ClangObject):
args_array = None
if len(args) > 0:
args_array = (c_string_p * len(args))()
for i,a in enumerate(args):
args_array[i] = c_string_p(a)
args_array = (c_char_p * len(args))(* args)
unsaved_array = None
if len(unsaved_files) > 0:
@ -2586,8 +2550,8 @@ class TranslationUnit(ClangObject):
if hasattr(contents, "read"):
contents = contents.read()
unsaved_array[i].name = c_string_p(name)
unsaved_array[i].contents = c_string_p(contents)
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,
@ -2642,7 +2606,7 @@ class TranslationUnit(ClangObject):
@property
def spelling(self):
"""Get the original translation unit source file name."""
return str(conf.lib.clang_getTranslationUnitSpelling(self))
return conf.lib.clang_getTranslationUnitSpelling(self)
def get_includes(self):
"""
@ -2765,9 +2729,9 @@ class TranslationUnit(ClangObject):
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
print(value)
print value
if not isinstance(value, str):
raise TypeError('Unexpected unsaved file contents.')
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)
@ -2829,11 +2793,11 @@ class TranslationUnit(ClangObject):
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
print(value)
print value
if not isinstance(value, str):
raise TypeError('Unexpected unsaved file contents.')
unsaved_files_array[i].name = c_string_p(name)
unsaved_files_array[i].contents = c_string_p(value)
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)
@ -2868,7 +2832,7 @@ class File(ClangObject):
@property
def name(self):
"""Return the complete file and path name of the file."""
return str(conf.lib.clang_getCString(conf.lib.clang_getFileName(self)))
return conf.lib.clang_getCString(conf.lib.clang_getFileName(self))
@property
def time(self):
@ -2876,7 +2840,7 @@ class File(ClangObject):
return conf.lib.clang_getFileTime(self)
def __str__(self):
return str(self.name)
return self.name
def __repr__(self):
return "<File: %s>" % (self.name)
@ -2945,12 +2909,12 @@ class CompileCommand(object):
@property
def directory(self):
"""Get the working directory for this CompileCommand"""
return str(conf.lib.clang_CompileCommand_getDirectory(self.cmd))
return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
@property
def filename(self):
"""Get the working filename for this CompileCommand"""
return str(conf.lib.clang_CompileCommand_getFilename(self.cmd))
return conf.lib.clang_CompileCommand_getFilename(self.cmd)
@property
def arguments(self):
@ -2962,7 +2926,7 @@ class CompileCommand(object):
"""
length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
for i in xrange(length):
yield str(conf.lib.clang_CompileCommand_getArg(self.cmd, i))
yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
class CompileCommands(object):
"""
@ -3056,7 +3020,7 @@ class Token(Structure):
This is the textual representation of the token in source.
"""
return str(conf.lib.clang_getTokenSpelling(self._tu, self))
return conf.lib.clang_getTokenSpelling(self._tu, self)
@property
def kind(self):
@ -3099,7 +3063,7 @@ functionList = [
[c_object_p]),
("clang_CompilationDatabase_fromDirectory",
[c_string_p, POINTER(c_uint)],
[c_char_p, POINTER(c_uint)],
c_object_p,
CompilationDatabase.from_result),
@ -3109,7 +3073,7 @@ functionList = [
CompileCommands.from_result),
("clang_CompilationDatabase_getCompileCommands",
[c_object_p, c_string_p],
[c_object_p, c_char_p],
c_object_p,
CompileCommands.from_result),
@ -3144,7 +3108,7 @@ functionList = [
c_uint),
("clang_codeCompleteAt",
[TranslationUnit, c_string_p, c_int, c_int, c_void_p, c_int, c_int],
[TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int],
POINTER(CCRStructure)),
("clang_codeCompleteGetDiagnostic",
@ -3160,7 +3124,7 @@ functionList = [
c_object_p),
("clang_createTranslationUnit",
[Index, c_string_p],
[Index, c_char_p],
c_object_p),
("clang_CXXConstructor_isConvertingConstructor",
@ -3310,7 +3274,7 @@ functionList = [
("clang_getCString",
[_CXString],
c_string_p),
c_char_p),
("clang_getCursor",
[TranslationUnit, SourceLocation],
@ -3457,7 +3421,7 @@ functionList = [
Type.from_result),
("clang_getFile",
[TranslationUnit, c_string_p],
[TranslationUnit, c_char_p],
c_object_p),
("clang_getFileName",
@ -3586,7 +3550,7 @@ functionList = [
("clang_getTUResourceUsageName",
[c_uint],
c_string_p),
c_char_p),
("clang_getTypeDeclaration",
[Type],
@ -3681,7 +3645,7 @@ functionList = [
bool),
("clang_parseTranslationUnit",
[Index, c_string_p, c_void_p, c_int, c_void_p, c_int, c_int],
[Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int],
c_object_p),
("clang_reparseTranslationUnit",
@ -3689,7 +3653,7 @@ functionList = [
c_int),
("clang_saveTranslationUnit",
[TranslationUnit, c_string_p, c_uint],
[TranslationUnit, c_char_p, c_uint],
c_int),
("clang_tokenize",
@ -3761,7 +3725,7 @@ functionList = [
Type.from_result),
("clang_Type_getOffsetOf",
[Type, c_string_p],
[Type, c_char_p],
c_longlong),
("clang_Type_getSizeOf",
@ -3820,8 +3784,7 @@ def register_functions(lib, ignore_errors):
def register(item):
return register_function(lib, item, ignore_errors)
for f in functionList:
register(f)
map(register, functionList)
class Config:
library_path = None

View File

@ -59,13 +59,9 @@ int SOME_DEFINE;
assert spellings[-1] == 'y'
def test_unsaved_files_2():
try:
from StringIO import StringIO
except:
from io import StringIO
import StringIO
tu = TranslationUnit.from_source('fake.c', unsaved_files = [
('fake.c', StringIO('int x;'))])
('fake.c', StringIO.StringIO('int x;'))])
spellings = [c.spelling for c in tu.cursor.get_children()]
assert spellings[-1] == 'x'