LibClang Python绑定函数“getOverridden”

时间:2016-03-12 19:45:50

标签: python libclang

LibClang公开了一个函数来“确定被给定方法覆盖的方法集”(解释here)。但是这个函数似乎没有在python绑定中公开。有人可以解释如何将这个功能添加到绑定中,还是我找不到它?

1 个答案:

答案 0 :(得分:0)

通常,向libclang添加方法遵循库本身使用的相同基本模式。

  1. 使用ctypes查找要包装的方法的句柄。
  2. 指定有关参数和返回类型的额外类型信息。
  3. 您将ctypes函数包装在处理任何极端情况/缓存的python函数中。
  4. 对于简单的情况,你可以使用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