14

C++ コードに次のマクロがあるとします。

_Foo(arg1, arg2)

Python を使用して、Clang と cindex.py で提供される Python バインディングを使用して、そのマクロのすべてのインスタンスとエクステントを見つけたいと考えています。Python の正規表現をコードで直接使用したくありません。これは 99% の方法で取得できますが、100% ではないからです。100% に到達するには、Clang のような実際の C++ パーサーを使用して、人々が構文的に正しく、コンパイルしても、正規表現では意味をなさないばかげたことを行うすべてのケースを処理する必要があるように私には思えます。ケースの 100% を処理する必要があり、Clang をコンパイラの 1 つとして使用しているため、このタスクのパーサーとしても Clang を使用することは理にかなっています。

次の Python コードを考えると、Clang の Python バインディングが認識している定義済みの型のように見えるものを見つけることができますが、マクロは認識できません。

def find_typerefs(node):
    ref_node = clang.cindex.Cursor_ref(node)
    if ref_node:
        print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (
            ref_node.spelling, ref_node.kind, node.data, node.extent, node.location.line, node.location.column)

# Recurse for children of this node
for c in node.get_children():
    find_typerefs(c)

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
find_typerefs(tu.cursor)

私が探していると思うのは、生の AST を自分のマクロの名前として解析する方法ですが、_FOO()よくわかりません。マクロの名前を渡して、Clang からエクステントまたはデータを取得できるようにするコードを誰かが提供できますか?

4

2 に答える 2

10

optionsに適切なフラグを渡す必要がありますIndex.parse

tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)

カーソル ビジターの残りの部分は次のようになります。

def visit(node):
    if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION, clang.cindex.CursorKind.MACRO_DEFINITION):
        print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column)
    for c in node.get_children():
        visit(c)
于 2013-06-28T20:44:02.263 に答える
0

libclang から取得した AST 全体をプリティプリントするスクリプトを書いたことがあります。これは、どの情報がどこにあるかを確認するためです。

ここにあります:https://gist.github.com/2503232

于 2013-02-25T19:09:08.400 に答える