使用 libclang 进行函数边界识别

Function boundary identification using libclang

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

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

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

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

我的问题是,如何获取函数位置的结尾

#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

您正在 Cursor class 上寻找 extent 属性。例如:

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

将 return 一个 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 的定义上。