LibClang предоставляет функцию «определять набор методов, которые переопределяются данным методом» (пояснил here). Однако эта функция, похоже, не отображается в привязках python. Может кто-нибудь объяснить, как добавить эту функцию в привязки или я просто не нашел ее?LibClang Функция связывания Python «getOverridden»
ответ
В общем, добавление методов к libclang следует тому же базовому шаблону, который используется в самой библиотеке.
- Вы используете ctypes для поиска дескриптора метода, который хотите обернуть.
- Указание дополнительной информации о аргументах и типах возвращаемых данных.
- Вы обертываете эту функцию ctypes в функции python, которая имеет дело с любыми угловыми случаями/кешированием.
Для простых случаев вы можете использовать cymbal, новый модуль Python, который вышел из некоторых экспериментов, пытаясь ответить на этот вопрос. Cymbal позволяет вам применять методы к типам и курсорам libclang.
Однако clang_getOverriddenCursors
немного сложнее, чем обычно, потому что вам нужно избавиться от памяти, возвращенной вызовом clang_disposeOverriddenCursors
.
Кроме того, libclang делает некоторую магию, что означает, что курсоры, которые вы получаете от этой функции, недействительны для всех вызовов функций (они опускают указатель на единицу перевода), поэтому вам также необходимо создавать обновленные курсоры (на основе блок перевода и местоположение).
Пример кода:
import clang.cindex
from clang.cindex import *
clang_getOverriddenCursors = clang.cindex.conf.lib.clang_getOverriddenCursors
clang_getOverriddenCursors.restype = None
clang_getOverriddenCursors.argtypes = [Cursor, POINTER(POINTER(Cursor)), POINTER(c_uint)]
clang_disposeOverriddenCursors = clang.cindex.conf.lib.clang_disposeOverriddenCursors
clang_disposeOverriddenCursors.restype = None
clang_disposeOverriddenCursors.argtypes = [ POINTER(Cursor) ]
def get_overriden_cursors(self):
cursors = POINTER(Cursor)()
num = c_uint()
clang_getOverriddenCursors(self, byref(cursors), byref(num))
updcursors = []
for i in xrange(int(num.value)):
c = cursors[i]
updcursor = Cursor.from_location(self._tu, c.location)
updcursors.append(updcursor)
clang_disposeOverriddenCursors(cursors)
return updcursors
Предполагая, что вы хотите, чтобы разобрать что-то вроде этого:
// sample.cpp
class foo {
public:
virtual void f();
};
class bar : public foo {
public:
virtual void f();
};
Вы можете найти методы в дереве
idx = Index.create()
tu = idx.parse('sample.cpp', args = '-x c++'.split())
methods = []
for c in tu.cursor.walk_preorder():
if c.kind == CursorKind.CXX_METHOD:
methods.append(c)
Вы можете увидеть переопределения
def show_method(method):
return method.semantic_parent.spelling + '::' + method.spelling
for m in methods:
for override in get_overriden_cursors(m):
print show_method(m), 'overrides', show_method(override)
Что для меня печатает:
bar::f overrides foo::f
Я нашел решение сам. Вывешивает его позже дома. – cwde