2016-10-27 52 views
1

我需要解析一個C++代碼文件,並使用完全限定名稱查找其中的所有函數調用。我使用libclang的Python綁定,因爲它看起來比編寫我自己的C++解析器容易,即使文檔是稀疏的。如何用libclang檢索完全限定的函數名?

實例C++代碼:

namespace a { 
    namespace b { 
    class Thing { 
    public: 
     Thing(); 
     void DoSomething(); 
     int DoAnotherThing(); 
    private: 
     int thisThing; 
    }; 
    } 
} 

int main() 
{ 
    a::b::Thing *thing = new a::b::Thing(); 
    thing->DoSomething(); 
    return 0; 
} 

Python腳本:

import clang.cindex 
import sys 

def find_function_calls(node): 
    if node.kind == clang.cindex.CursorKind.CALL_EXPR: 
    # What do I do here? 
    pass 
    for child in node.get_children(): 
    find_function_calls(child) 

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

我在尋找的輸出的功能完全限定名稱的列表被稱爲是:

a::b::Thing::Thing 
a::b::Thing::DoSomething 

我可以通過使用node.spelling獲得函數的「short」名稱,但我不知道如何找到它屬於的類/名稱空間。

回答

2

您可以使用光標referenced屬性獲取定義的句柄,然後您可以通過semantic_parent屬性(停止在根位置或當光標類型是翻譯單元時)遞增AST以構建完全限定名稱。

import clang.cindex 
from clang.cindex import CursorKind 

def fully_qualified(c): 
    if c is None: 
     return '' 
    elif c.kind == CursorKind.TRANSLATION_UNIT: 
     return '' 
    else: 
     res = fully_qualified(c.semantic_parent) 
     if res != '': 
      return res + '::' + c.spelling 
    return c.spelling 

idx = clang.cindex.Index.create() 
tu = idx.parse('tmp.cpp', args='-xc++ --std=c++11'.split()) 
for c in tu.cursor.walk_preorder(): 
    if c.kind == CursorKind.CALL_EXPR: 
     print fully_qualified(c.referenced) 

主要生產:

a::b::Thing::Thing 
a::b::Thing::DoSomething 
相關問題