5

I am learning to parse C++ files using Python + libclang with the help of this very informative (but slightly outdated) tutorial by Eli Bendersky.

My objective is to parse C++ files and identify the function boundaries for functions present in those file. I am expecting to build a python dictionary of this form:

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

To this end, I am able to get the function name (using cursor.spelling for AST nodes that are of CursorKind.FUNCTION_DECL or CursorKind.CXX_METHOD kind) and the start location (using cursor.location)

My question is, how do I get the end of function location

Maggie
  • 5,923
  • 8
  • 41
  • 56

2 Answers2

5

You're looking for the extent property on the Cursor class. For example:

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

Will return a Python equivalent of a source range:

<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>>

You may want to consider restricting attention to definitions using Cursor.is_definition if you want function bodies rather than just their declarations.

Andrew Walker
  • 40,984
  • 8
  • 62
  • 84
-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

hailinzeng
  • 966
  • 9
  • 24