如何访问序列化的 clang 抽象语法树 (AST)

How to visit a serialized clang abstract syntax tree (AST)

本文关键字:clang 抽象 语法树 AST 序列化 访问 何访问      更新时间:2023-10-16

我已经能够实现一个ASTFrontendAction来创建ASTConsumer,它使用RescursiveASTVisitor遍历翻译单元decl,从而访问给定源文件的AST的所有节点。 我通过实现传递给ClangTool::run(ToolAction *action)ToolAction来做到这一点。 此工具覆盖ToolAction::runInvocation成员函数,以便在每次调用我的ASTFrontendAction之间进行一些处理。 到目前为止一切顺利,一切都按预期工作,我的自定义 clang 工具正在帮助我更好地探索一个相当大的、超过 15 年的代码库。

但是,每次我想运行我的工具时,我都需要对 AST 进行完整的解析。 正如我所提到的,这是一个相当大的代码库,因此进行一次运行需要一段时间。 通过查看代码,我了解到可以从保存的文件创建和遍历 AST,而不是执行解析。 谷歌搜索确认可以保存 AST,并且通过查看ClangToolASTUnitAPI,这似乎很容易做到。

虽然保存AST 似乎很简单,但我不知道在运行我的自定义 clang 工具时如何使用保存的 AST。 查看运行工具的代码路径,我看到有一个点是通过解析源文件或从文件中读取 AST 来创建的。 我想做的是将我的所有 AST 都放在一个文件中,以便每次运行我的工具都会从文件创建 AST,而不需要执行完整解析(我认为这会快得多)。

有人可以帮忙吗? 提前感谢!

这对我有用:

clang::CompilerInstance CI;
CI.createDiagnostics();
std::shared_ptr<clang::TargetOptions> TO = std::make_shared<clang::TargetOptions>();
TO->Triple = "x86_64-pc-win32"; // see clang -v
CI.setTarget(clang::TargetInfo::CreateTargetInfo(CI.getDiagnostics(), TO));
std::unique_ptr<ASTUnit> ast = ASTUnit::LoadFromASTFile("TheAstFile.ast", 
CI.getPCHContainerReader(), 
ASTUnit::LoadEverything, 
&CI.getDiagnostics(), 
CI.getFileSystemOpts());
MyAstConsumer consumer(ast->getASTContext());
consumer.HandleTranslationUnit(ast->getASTContext());