我有以下脚本尝试打印给定C文件中的所有AST节点.当在一个包含简单包含的简单文件(同一目录中的头文件等)上使用它时,这可以正常工作.
#!/usr/bin/env python from argparse import ArgumentParser,FileType from clang import cindex def node_info(node): return {'kind': node.kind,'usr': node.get_usr(),'spelling': node.spelling,'location': node.location,'file': node.location.file.name,'extent.start': node.extent.start,'extent.end': node.extent.end,'is_definition': node.is_definition() } def get_nodes_in_file(node,filename,ls=None): ls = ls if ls is not None else [] for n in node.get_children(): if n.location.file is not None and n.location.file.name == filename: ls.append(n) get_nodes_in_file(n,ls) return ls def main(): arg_parser = ArgumentParser() arg_parser.add_argument('source_file',type=FileType('r+'),help='C++ source file to parse.') arg_parser.add_argument('compilation_database',help='The compile_commands.json to use to parse the source file.') args = arg_parser.parse_args() compilation_database_path = args.compilation_database.name source_file_path = args.source_file.name clang_args = ['-x','c++','-std=c++11','-p',compilation_database_path] index = cindex.Index.create() translation_unit = index.parse(source_file_path,clang_args) file_nodes = get_nodes_in_file(translation_unit.cursor,source_file_path) print [p.spelling for p in file_nodes] if __name__ == '__main__': main()
但是,我得到了一个clang.cindex.TranslationUnitLoadError:解析翻译单元时出错.当我运行脚本并提供一个在其父目录中具有compile_commands.json文件的有效C文件时.这段代码使用带有clang的CMake运行并构建得很好,但我似乎无法弄清楚如何正确地传递指向compile_commands.json的参数.
我也很难在clang文档中找到这个选项,并且无法使-ast-dump工作.但是,通过传递文件路径,clang-check工作正常!
解决方法
你自己接受的答案是不正确的. libclang
does support compilation databases和
so does cindex.py,libclang python绑定.
混淆的主要原因可能是libclang知道/使用的编译标志只是可以传递给clang前端的所有参数的子集.编译数据库受支持但不能自动运行:必须手动加载和查询.这样的事情应该有效:
#!/usr/bin/env python from argparse import ArgumentParser,FileType from clang import cindex compilation_database_path = args.compilation_database.name source_file_path = args.source_file.name index = cindex.Index.create() # Step 1: load the compilation database compdb = cindex.CompilationDatabase.fromDirectory(compilation_database_path) # Step 2: query compilation flags try: file_args = compdb.getCompileCommands(source_file_path) translation_unit = index.parse(source_file_path,file_args) file_nodes = get_nodes_in_file(translation_unit.cursor,source_file_path) print [p.spelling for p in file_nodes] except CompilationDatabaseError: print 'Could not load compilation flags for',source_file_path