簡體   English   中英

如何使用clang python綁定獲取類方法定義?

[英]How to get class method definitions using clang python bindings?

給出以下C ++文件:

class Foo
{
public:
  Foo();

  void bar(int input);

  void another(int input, double & output);
};

void
Foo::bar(int input)
{
  input += 1;
}

void
Foo::another(int input, double & output)
{
  input += 1;
  output = input * 1.2345;
}

如何利用clang python綁定來提取兩種方法的定義。 我可以使用下面的python腳本獲取類聲明,但我似乎無法弄清楚如何提取完整的方法。 例如,我想要這個信息:

void
Foo::another(int input, double & output)
{
  input += 1;
  output = input * 1.2345;
}

Python腳本:

#!/usr/bin/env python
import clang.cindex
clang.cindex.Config.set_library_path('/opt/moose/llvm-3.7.0/lib')

def getCursors(cursor, output, kind):
    """
    Recursively extract all the cursors of the given kind.
    """
    for c in cursor.get_children():
        if c.kind == kind:
            output.append(c)
        getCursors(c, output, kind)

if __name__ == '__main__':

    # Parse the test file
    index = clang.cindex.Index.create()
    tu = index.parse('method.C', ['-x', 'c++'])

    # Extract the parsers
    output = []
    getCursors(tu.cursor, output, clang.cindex.CursorKind.CXX_METHOD)

    # Print the method declarations (How to I get the definitions?)
    for c in output:
        defn = c.get_definition() # Gives nothing
        print defn 
        print c.extent.start.file, c.extent.start.line, c.extent.end.line # Gives decleration

跟進:

建議使用以下函數作為解決方案,但它不適用於clang 3.7。 在發布之前我無法更新到3.9,我需要支持最新的兩個版本的clang(3.7和3.8)。 如果添加print語句,則結果表明未找到定義。

def method_definitions(cursor):
    for i in cursor.walk_preorder():
        print i.kind, i.is_definition() # Added this
        if i.kind != CursorKind.CXX_METHOD:
            continue
        if not i.is_definition():
            continue
        yield i

運行該方法產生以下結果,任何人都知道clang 3.7和3.9之間發生了什么變化?

CursorKind.TRANSLATION_UNIT False
CursorKind.CLASS_DECL True
CursorKind.CXX_ACCESS_SPEC_DECL True
CursorKind.CONSTRUCTOR False
CursorKind.CXX_METHOD False
CursorKind.PARM_DECL True
CursorKind.CXX_METHOD False
CursorKind.PARM_DECL True
CursorKind.PARM_DECL True

你非常接近 - 訣竅是使用光標偏移而不是行/列,而AFAIK,libclang不公開源的字節,所以你需要自己閱讀文本。

以下測試:

  • Clang由Xcode 7.3(7D175)提供 - OSX Apple LLVM版本7.3.0(clang-703.0.29)和來自pypi的pip安裝綁定( pip install 'clang==3.7' install'clang pip install 'clang==3.7'
  • Ubuntu clang版本3.7.1-svn253742-1~exp1(branches / release_37)(基於LLVM 3.7.1)
  • Ubuntu clang版本3.6.2-svn240577-1~exp1(branches / release_36)(基於LLVM 3.6.2)
  • clang version 3.9.0-svn267343-1~exp1(trunk)

唯一需要注意的是,對於帶有宏/頭YMMV的更復雜的情況。

import clang.cindex
from clang.cindex import *

def method_definitions(cursor):
    for i in cursor.walk_preorder():
        if i.kind != CursorKind.CXX_METHOD:
            continue
        if not i.is_definition():
            continue
        yield i

def extract_definition(cursor):
    filename = cursor.location.file.name
    with open(filename, 'r') as fh:
        contents = fh.read()
    return contents[cursor.extent.start.offset: cursor.extent.end.offset]

idx = Index.create()
tu = idx.parse('method.C', ['-x', 'c++'])
defns = method_definitions(tu.cursor)
for defn in defns:
    print extract_definition(defn)

這使:

void
Foo::bar(int input)
{
      input += 1;
}
void
Foo::another(int input, double & output)
{
      input += 1;
        output = input * 1.2345;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM