我正在尝试使用Clang python绑定检索类的完整层次结构。
基本上我在做什么:
CLASS_DECL
光标。CXX_BASE_SPECIFIER
节点。get_definition()
或type.get_declaration()
获取父声明但是,当父类是模板时,我遇到了问题。我已经附上了一个显示问题的简单示例。
import clang.cindex
clang.cindex.Config.set_library_file('/usr/lib/llvm-6.0/lib/libclang.so')
def get_template_args(node):
t = node.type
if t.get_num_template_arguments() < 0:
return []
for i in range(t.get_num_template_arguments()):
yield t.get_template_argument_type(i)
def str_node_type(node):
if isinstance(node, clang.cindex.Cursor):
return '[K={}] [S={}] [DN={}] [ISDEF: {}]'.format(node.kind, node.spelling, node.displayname,
node.is_definition())
else:
return '[K={}] [Type:{}]'.format(node.kind, node.spelling)
def find_parent2(node):
print('\tFind parent2')
print('\t\tNode {}'.format(str_node_type(node)))
print('\t\tNum template args: {}'.format(node.canonical.get_num_template_arguments()))
for c in node.get_children():
if c.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER:
print('\t\tFound base: {}'.format(str_node_type(c)))
def find_parent(classdecl_node):
for c in classdecl_node.get_children():
if c.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER:
print('\tFound base: {}'.format(str_node_type(c)))
definition = c.get_definition()
print('\tTemplate arguments for type {}: {}'.format(str_node_type(definition.type),
definition.type.get_num_template_arguments()))
for a in get_template_args(c):
print('\t\tArg: {}'.format(str_node_type(a)))
find_parent2(c.type.get_declaration()) # or find_parent2(definition)
def main():
tu = clang.cindex.TranslationUnit.from_source('class.cpp', ['-std=c++11', '-O0'],
options=clang.cindex.TranslationUnit.PARSE_INCOMPLETE | clang.cindex.TranslationUnit.PARSE_SKIP_FUNCTION_BODIES)
for node in tu.cursor.get_children():
if (node.kind == clang.cindex.CursorKind.CLASS_DECL or
node.kind == clang.cindex.CursorKind.STRUCT_DECL):
print('Found class declaration:{}'.format(str_node_type(node)))
find_parent(node)
if __name__ == "__main__":
main()
正在解析的相应C ++文件:
template<typename T>
class GrandParent
{
};
template<typename T>
class Parent : public GrandParent<T> {};
class VerySimple {};
class Simple : public VerySimple {};
class Child : public Parent<int>, public Simple
{
};
通过阅读输出,我们可以看到我们能够找到VerySimple
类,它是一个非模板的祖父母。但是,我们看不到GrandParent
这是一个模板类。
Found class declaration:[K=CursorKind.CLASS_DECL] [S=VerySimple] [DN=VerySimple] [ISDEF: True]
Found class declaration:[K=CursorKind.CLASS_DECL] [S=Simple] [DN=Simple] [ISDEF: True]
Found base: [K=CursorKind.CXX_BASE_SPECIFIER] [S=class VerySimple] [DN=class VerySimple] [ISDEF: False]
Template arguments for type [K=TypeKind.RECORD] [Type:VerySimple]: -1
Find parent2
Node [K=CursorKind.CLASS_DECL] [S=VerySimple] [DN=VerySimple] [ISDEF: True]
Num template args: -1
Found class declaration:[K=CursorKind.CLASS_DECL] [S=Child] [DN=Child] [ISDEF: True]
Found base: [K=CursorKind.CXX_BASE_SPECIFIER] [S=Parent<int>] [DN=Parent<int>] [ISDEF: False]
Template arguments for type [K=TypeKind.RECORD] [Type:Parent<int>]: 1
Arg: [K=TypeKind.INT] [Type:int]
Find parent2
Node [K=CursorKind.CLASS_DECL] [S=Parent] [DN=Parent<int>] [ISDEF: True]
Num template args: -1
Found base: [K=CursorKind.CXX_BASE_SPECIFIER] [S=class Simple] [DN=class Simple] [ISDEF: False]
Template arguments for type [K=TypeKind.RECORD] [Type:Simple]: -1
Find parent2
Node [K=CursorKind.CLASS_DECL] [S=Simple] [DN=Simple] [ISDEF: True]
Num template args: -1
Found base: [K=CursorKind.CXX_BASE_SPECIFIER] [S=class VerySimple] [DN=class VerySimple] [ISDEF: False]
我不确定在这里我缺少什么或误会了。