我試圖從類實例化C++中使用python-clang
,即提取模板參數。 Python的綁定爲libclang
(與clang
3.9)。例如,對於python-clang:獲取模板參數
template <typename T> class X {};
X<bool> x;
我希望能夠弄清楚,X
實例化一個bool
作爲模板參數。
首先,它似乎有些功能,如get_num_template_arguments
,不通過python-clang
擺在首位,這是在cymbal似乎開始發揮作用,以猴補丁python-clang
曝光。
有了這個,我能夠遠遠地得到這樣的:
#!/usr/bin/env python
import clang.cindex
clang.cindex.Config.set_library_file('/usr/lib/x86_64-linux-gnu/libclang-3.9.so.1')
index = clang.cindex.Index.create()
source = """
template <typename T> class X {};
X<bool> x;
"""
######### stolen from cymbal
from ctypes import c_uint, c_int
def find_libclang_function(function):
return getattr(clang.cindex.conf.lib, function)
def monkeypatch_helper(classtype, name, library_function, args, result):
if hasattr(classtype, name):
raise ('failed to add method, %s is already available' % name)
f = find_libclang_function(library_function)
f.argtypes = args
f.restype = result
def impl(*args):
return f(*args)
setattr(classtype, name, impl)
def monkeypatch_type(method_name, library_function, args, result):
monkeypatch_helper(clang.cindex.Type, method_name, library_function, args, result)
monkeypatch_type('get_template_argument_type',
'clang_Type_getTemplateArgumentAsType',
[clang.cindex.Type, c_uint],
clang.cindex.Type)
monkeypatch_type('get_num_template_arguments',
'clang_Type_getNumTemplateArguments',
[clang.cindex.Type],
c_int)
######### /stolen from cymbal
# helpers for visiting the AST recursively
def visit(node, func):
func(node)
for c in node.get_children():
visit(c, func)
def visit_depth(node, func, depth=0):
func(node, depth)
for c in node.get_children():
visit_depth(c, func, depth+1)
# parse the TU
tu = clang.cindex.TranslationUnit.from_source('t.cpp', ['-std=c++11'], unsaved_files=[('t.cpp', source)])
# show the AST
def astprinter(node, depth):
print " "*depth, node.kind, node.spelling
visit_depth(tu.cursor, astprinter)
# find everything with a template and try to extract the template argument
def template_finder(node):
if hasattr(node, 'type') and node.type.get_num_template_arguments() != -1:
print node.type.get_num_template_arguments(), node.spelling, node.kind, node.get_template_argument_type(0).kind
visit(tu.cursor, template_finder)
此輸出:
CursorKind.TRANSLATION_UNIT t.cpp
CursorKind.CLASS_TEMPLATE X
CursorKind.TEMPLATE_TYPE_PARAMETER T
CursorKind.VAR_DECL x
CursorKind.TEMPLATE_REF X
CursorKind.CALL_EXPR X
1 x CursorKind.VAR_DECL TypeKind.INVALID
1 X CursorKind.CALL_EXPR TypeKind.INVALID
我期待node.get_template_argument_type(0).kind
在template_finder
返回的東西,帶給我bool
,但我找不到任何東西。這是正確的路嗎?是否有可能獲得當前狀態python-clang
的模板參數?
只是一個關於cy的澄清 - 這是一個很大的阻止差距,是爲了防止任何人不得不復制和粘貼代碼注入使用ctypes功能。 自從它發佈以來,出現了一些重要的重構(例如/ clang.cindex> = 3.9,現在有一個register_function),這使得它不重要。 –
關於cymbal的許可 - 它是根據MIT許可發佈的,所以如果您做出適當的歸屬,重用/回收您喜歡的任何代碼就可以了。 –