libclang の Python binding を使用する 〜 型名の取得 〜

前回は Type について簡単に書きました。
今回はその Type の名前を取得する方法について書きます。

[注意]

今回使用している clang_getTypeSpelling なのですが、Clang 3.3 以前の python binding を使用している場合はユーザ側で動的ライブラリから呼び出せるように設定しておく必要があります。
Clang 3.4 以降の python binding の場合は clang_getTypeSpelling が Type.spelling から呼び出すように設定されているので clang_getTypeSpelling を設定する必要はありません。

[ソース]

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

# Clang 3.3 の python binding を使用した場合、
# lib に設定されていないので
# ユーザ側で設定しておく必要がある
conf = Config()
conf.lib.clang_getTypeSpelling.restype  = _CXString
conf.lib.clang_getTypeSpelling.argtypes = [Type]
conf.lib.clang_getTypeSpelling.errcheck = _CXString.from_result

def type_spelling(type):
    return conf.lib.clang_getTypeSpelling(type)


# source code
source = """
int
main(){
    int value;
    value = 0;
    
    int* ptr;
    ptr = &value;
    
    struct X{};
    X x;
    x;
    
    auto px = &x;
    px;
    return 0;
}
"""

index = clang.cindex.Index.create()

tu = index.parse("test.cpp", args = ["-std=c++11 "], 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)

# Type の情報を出力
def print_type(type):
    print "kind : %s" % type.kind
    print "spelling : %s" % type_spelling(type)


cursor1 = make_cursor("test.cpp", 4, 5)
print_type(cursor1.type)


cursor2 = make_cursor("test.cpp", 7, 5)
print_type(cursor2.type)

cursor3 = make_cursor("test.cpp", 11, 5)
print_type(cursor3.type)

cursor4 = make_cursor("test.cpp", 15, 5)
print_type(cursor4.type)

[出力]

kind : TypeKind.INT
spelling : int
kind : TypeKind.POINTER
spelling : int *
kind : TypeKind.RECORD
spelling : X
kind : TypeKind.UNEXPOSED
spelling : X *


簡単にですが、こんな感じで使用することができます。
auto を使用した場合の型名なども取得する事ができます。

[Clang]

  • clang++ (LLVM) 3.3