libclang の Python binding を使用する 〜 definition 編〜

前回は Cursor に関する記事を書きました。
次は型情報について書く予定だったのですが、先に definition 周りについて書きます。
さて、定義位置は Cursor の get_definition() メソッドを使用して取得する事ができます。

[ソース]

# -*- coding: utf-8 -*
import clang.cindex
from clang.cindex import Cursor
from clang.cindex import Config

Config.set_compatibility_check(False)
Config.set_library_path("D:/LLVM/BUILD_3_3/bin")


# source code
source = """\

// 宣言のみの関数
void
func1();

// 先に宣言し、後から定義する関数
void
func2(int);

// 定義のみの関数
void
func3(int, float){

}

// func2() の定義
void
func2(int){

}

int
main(){
    func1();
    func2(1);
    func3(1, 3.31f);
    return;
}
"""

index = clang.cindex.Index.create()

tu = index.parse("test.cpp", unsaved_files = [ ("test.cpp", source)])

# Cursor の生成
def make_cursor(file, line, col):
    # location を定義
    location = tu.get_location(file, (line, col))
    
    # location からその位置の cursor を取得
    return Cursor.from_location(tu, location)


# Cursor の情報を出力
def print_cursor(cursor):
    if cursor is None:
        print "None"
        return
    print "displayname: %s" % cursor.displayname
    print "spelling   : %s" % cursor.spelling
    print "kind       : %s" % cursor.kind
    print "location   : %s" % cursor.location

def1 = make_cursor("test.cpp", 24, 2)
print "-------- cursor func1() --------"
print_cursor(def1)
print "-------- definition func1() --------"
print_cursor(def1.get_definition())

print ""

def2 = make_cursor("test.cpp", 25, 2)
print "-------- cursor --------"
print_cursor(def2)
print "-------- definition func2() --------"
print_cursor(def2.get_definition())

print ""

def3 = make_cursor("test.cpp", 26, 2)
print "-------- cursor func3() --------"
print_cursor(def3)
print "-------- definition func3() --------"
print_cursor(def3.get_definition())

[出力]

-------- cursor func1() --------
displayname: func1
spelling   : None
kind       : CursorKind.DECL_REF_EXPR
location   : <SourceLocation file 'test.cpp', line 24, column 2>
-------- definition func1() --------
None

-------- cursor --------
displayname: func2
spelling   : None
kind       : CursorKind.DECL_REF_EXPR
location   : <SourceLocation file 'test.cpp', line 25, column 2>
-------- definition func2() --------
displayname: func2(int)
spelling   : func2
kind       : CursorKind.FUNCTION_DECL
location   : <SourceLocation file 'test.cpp', line 18, column 1>

-------- cursor func3() --------
displayname: func3
spelling   : None
kind       : CursorKind.DECL_REF_EXPR
location   : <SourceLocation file 'test.cpp', line 26, column 2>
-------- definition func3() --------
displayname: func3(int, float)
spelling   : func3
kind       : CursorKind.FUNCTION_DECL
location   : <SourceLocation file 'test.cpp', line 12, column 1>


Cursor の get_definition() メソッドはその位置のオブジェクトが定義されている位置の Cursor を返します。
上記の例は関数のみですが型や変数などにも同様に利用することができます。
また、宣言のみで定義がない場合は None が返ってきます。
次は referenced について書く予定。

[Clang]

  • clang++ (LLVM) 3.3