jw_*_*jw_ 5 c++ clang libtooling
使用 Clang LibTooling 的最小源,这是一种非常常见的方式:
#include "pch.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "clang/Driver/Options.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include <iostream>
using namespace std;
using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;
class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
public:
explicit ExampleVisitor(CompilerInstance *CI) {}
};
class ExampleASTConsumer : public ASTConsumer {
private:
CompilerInstance *CI;
public:
explicit ExampleASTConsumer(CompilerInstance *CI) : CI(CI) {}
virtual void HandleTranslationUnit(ASTContext &Context) {
ExampleVisitor(CI).TraverseDecl(Context.getTranslationUnitDecl());
}
};
class ExampleFrontendAction : public ASTFrontendAction {
public:
virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) {
return std::unique_ptr<ASTConsumer>(new ExampleASTConsumer(&CI));
}
};
void run(int argc, const char **argv, llvm::cl::OptionCategory& tc) {
CommonOptionsParser op(argc, argv, tc);
ClangTool Tool(op.getCompilations(), op.getSourcePathList());
std::cout <<"getSourcePathList.size="<< op.getSourcePathList().size()<<"\n";
int result = Tool.run(newFrontendActionFactory<ExampleFrontendAction>().get());
}
int main(int argc, const char **argv) {
llvm::cl::OptionCategory tc1("c1");
llvm::cl::OptionCategory tc2("c2");
llvm::cl::OptionCategory tc3("c3");
run(argc, argv,tc1);
run(argc, argv,tc2);
run(argc, argv,tc3);
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
调试应用程序的参数是:
"the_only_source_file_to_scan.cpp" --
Run Code Online (Sandbox Code Playgroud)
这很好。
输出是(来自 main() 上面的“run”方法):
getSourcePathList.size=1
getSourcePathList.size=2
getSourcePathList.size=3
Run Code Online (Sandbox Code Playgroud)
问题是 main() 使用上述相同的参数调用 run() 3 次,其中只包含 1 个要扫描的源文件,但每次存储在 CommonOptionsParser 中的源待扫描列表的大小都会增加一(该列表与从 argv 输入的文件相同),它似乎只是每次将要扫描的源文件附加到列表中。
上述所有内容都保存在每次运行时新创建的临时变量中,那么 LibTooling 如何以及为何保留上次运行的状态以及如何“重置”这些状态?
小智 1
useFixedCompilationDatabase可以规避这个问题,它可以在一个进程中运行多个 clangTool