使用libclang进行函数边界识别

时间:2017-04-17 22:24:37

标签: python clang llvm clang++ libclang

我正在学习使用Python + libclang解析C ++文件,并借助Eli Bendersky这篇内容丰富(但略显过时)的教程。

我的目标是解析C ++文件并识别这些文件中存在的函数的函数边界。我期望构建一个这种形式的python字典:

{<func_name>:(<func_start_loc>, <func_end_loc>), ...}

为此,我能够获取函数名称(使用cursor.spelling用于CursorKind.FUNCTION_DECLCursorKind.CXX_METHOD类型的AST节点)和起始位置(使用{{1 }})

我的问题是,我如何获得功能位置的结束

2 个答案:

答案 0 :(得分:2)

您正在寻找extent课程中的Cursor媒体资源。例如:

s = '''
void f();
void g() 
{}
void f() 
{}
'''

idx = clang.cindex.Index.create()
tu = idx.parse('tmp.cpp', unsaved_files=[('tmp.cpp', s)])
for f in tu.cursor.walk_preorder():
    if f.kind == CursorKind.FUNCTION_DECL:
        print f.extent

将返回Python等效的源范围:

<SourceRange start <SourceLocation file 'tmp.cpp', line 2, column 1>, end <SourceLocation file 'tmp.cpp', line 2, column 9>>
<SourceRange start <SourceLocation file 'tmp.cpp', line 3, column 1>, end <SourceLocation file 'tmp.cpp', line 4, column 3>>
<SourceRange start <SourceLocation file 'tmp.cpp', line 5, column 1>, end <SourceLocation file 'tmp.cpp', line 6, column 3>>

如果您需要函数体而不仅仅是它们的声明,您可能需要考虑使用Cursor.is_definition来限制对定义的注意。

答案 1 :(得分:-1)

#include "clang/Basic/SourceManager.h"

FunctionDecl *f;

SourceLocation ST = f->getSourceRange().getBegin();
SourceLocation ED = f->getSourceRange().getEnd();

https://github.com/eliben/llvm-clang-samples/blob/master/src_clang/rewritersample.cpp

https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html https://clang.llvm.org/doxygen/classclang_1_1SourceRange.html