2016-10-27 22 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 
相关问题