1

LibClang は、「指定されたメソッドによってオーバーライドされるメソッドのセットを決定する」関数を公開します (ここで説明されています)。ただし、この関数は python バインディングで公開されていないようです。誰かがこの関数をバインディングに追加する方法を説明できますか、それとも見つけられませんでしたか?

4

1 に答える 1

0

一般に、libclang へのメソッドの追加は、ライブラリ自体で使用されるのと同じ基本パターンに従います。

  1. ctypes を使用して、ラップするメソッドへのハンドルを見つけます。
  2. 引数と戻り値の型に関する追加の型情報を指定します。
  3. そのctypes関数を、コーナーケース/キャッシングを処理するpython関数にラップします。

単純なケースでは、この質問に答えようとするいくつかの実験から生まれた新しい Python モジュールであるcymbalを使用できます。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
于 2016-05-07T08:05:45.453 に答える