运行 多次 clang 传递
running multiple clang passes
我一直在使用 Tool.run(ToolAction)
到 运行 clang 工具。如果我想在同一个输入源上 运行 多个工具,我是否只是创建不同的 ToolAction
并一个接一个地调用 Tool.run
?或者我是否以某种方式将 ASTFrontendAction
链接在一起?
这取决于你想要达到什么。
如果你想解析一次,然后用 AST 做多件事,你最好实现多个 ASTConsumers。
然后你可以创建聚合 ASTConsumer:
class AggregateASTConsumer : public clang::ASTConsumer {
public:
void HandleTranslationUnit(clang::ASTContext& Ctx) override {
for (auto consumer: consumers)
consumer.HandleTranslationUnit(Ctx);
}
std::vector<ASTConsumer*> consumers;
}
但是如果您想使用一些不同的选项重新解析输入源代码,那么您应该 运行 多次使用工具。
假设您有一个名为 Tool
的 ClangTool
和两个名为 MatchFinder1
和 MatchFinder2
的 MatchFinder
(已经添加了适当的匹配器),直接转换是:
std::vector<std::unique_ptr<ASTUnit>> ASTs;
Tool.buildASTs(ASTs);
for(auto& ast : ASTs) {
// First pass
MatchFinder1.matchAST(ast->getASTContext());
// Second pass
MatchFinder2.matchAST(ast->getASTContext());
}
这样,AST 节点在不同的匹配器运行之间保持有效,并且可以相互正确比较。
请注意,这种方法根本没有使用 FrontendAction
,但老实说,我不完全确定它实际上 做了什么。
我一直在使用 Tool.run(ToolAction)
到 运行 clang 工具。如果我想在同一个输入源上 运行 多个工具,我是否只是创建不同的 ToolAction
并一个接一个地调用 Tool.run
?或者我是否以某种方式将 ASTFrontendAction
链接在一起?
这取决于你想要达到什么。
如果你想解析一次,然后用 AST 做多件事,你最好实现多个 ASTConsumers。
然后你可以创建聚合 ASTConsumer:
class AggregateASTConsumer : public clang::ASTConsumer {
public:
void HandleTranslationUnit(clang::ASTContext& Ctx) override {
for (auto consumer: consumers)
consumer.HandleTranslationUnit(Ctx);
}
std::vector<ASTConsumer*> consumers;
}
但是如果您想使用一些不同的选项重新解析输入源代码,那么您应该 运行 多次使用工具。
假设您有一个名为 Tool
的 ClangTool
和两个名为 MatchFinder1
和 MatchFinder2
的 MatchFinder
(已经添加了适当的匹配器),直接转换是:
std::vector<std::unique_ptr<ASTUnit>> ASTs;
Tool.buildASTs(ASTs);
for(auto& ast : ASTs) {
// First pass
MatchFinder1.matchAST(ast->getASTContext());
// Second pass
MatchFinder2.matchAST(ast->getASTContext());
}
这样,AST 节点在不同的匹配器运行之间保持有效,并且可以相互正确比较。
请注意,这种方法根本没有使用 FrontendAction
,但老实说,我不完全确定它实际上 做了什么。