我正在尝试使用此自定义clang工具。我可以毫无问题地构建它,但是当我尝试在简单示例上运行它时,我会收到很多关于using
的错误。
当我从测试程序中删除include(和printf)时,我可以毫无问题地运行它。我假设我可能需要该文件的编译数据库,但我不知道如何在代码中创建一个。有人可以帮助我和/或让我走上正确的道路吗?示例来自http://eli.thegreenplace.net。我正在使用最新的clang和llvm以及VS 2012.为了运行该工具,我在工具的构建目录中使用命令:tool.exe test.c --
。
工具tool.exe
:
#include <sstream>
#include "clang/AST/AST.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 "llvm/Support/raw_ostream.h"
using namespace std;
using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;
static llvm::cl::OptionCategory ToolingSampleCategory("Tooling Sample");
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor>
{
public:
MyASTVisitor(Rewriter &R) : TheRewriter(R) {}
bool VisitStmt(Stmt *s) {
if (isa<IfStmt>(s))
{
IfStmt *IfStatement = cast<IfStmt>(s);
Stmt *Then = IfStatement->getThen();
TheRewriter.InsertText(Then->getLocStart(), "// the 'if' part\n", true,
true);
Stmt *Else = IfStatement->getElse();
if (Else)
TheRewriter.InsertText(Else->getLocStart(), "// the 'else' part\n",
true, true);
}
return true;
}
bool VisitFunctionDecl(FunctionDecl *f) {
if (f->hasBody()) {
Stmt *FuncBody = f->getBody();
QualType QT = f->getReturnType();
std::string TypeStr = QT.getAsString();
DeclarationName DeclName = f->getNameInfo().getName();
std::string FuncName = DeclName.getAsString();
std::stringstream SSBefore;
SSBefore << "// Begin function " << FuncName << " returning " << TypeStr
<< "\n";
SourceLocation ST = f->getSourceRange().getBegin();
TheRewriter.InsertText(ST, SSBefore.str(), true, true);
std::stringstream SSAfter;
SSAfter << "\n// End function " << FuncName;
ST = FuncBody->getLocEnd().getLocWithOffset(1);
TheRewriter.InsertText(ST, SSAfter.str(), true, true);
}
return true;
}
private:
Rewriter &TheRewriter;
};
class MyASTConsumer : public ASTConsumer
{
public:
MyASTConsumer(Rewriter &R) : Visitor(R) {}
bool HandleTopLevelDecl(DeclGroupRef DR) override {
for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {
Visitor.TraverseDecl(*b);
(*b)->dump();
}
return true;
}
private:
MyASTVisitor Visitor;
};
class MyFrontendAction : public ASTFrontendAction
{
public:
MyFrontendAction() {}
void EndSourceFileAction() override {
SourceManager &SM = TheRewriter.getSourceMgr();
llvm::errs() << "** EndSourceFileAction for: "
<< SM.getFileEntryForID(SM.getMainFileID())->getName() << "\n";
TheRewriter.getEditBuffer(SM.getMainFileID()).write(llvm::outs());
}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef file) override {
llvm::errs() << "** Creating AST consumer for: " << file << "\n";
TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
return llvm::make_unique<MyASTConsumer>(TheRewriter);
}
private:
Rewriter TheRewriter;
};
int main(int argc, const char **argv) {
CommonOptionsParser op(argc, argv, ToolingSampleCategory);
ClangTool Tool(op.getCompilations(), op.getSourcePathList());
Tool.run(newFrontendActionFactory<MyFrontendAction>().get());
return 0;
}
测试计划test.c
:
#include <cstdio>
void foo(int* a, int *b) {
if (a[0] > 1) {
b[0] = 2;
printf("%d", b[0]);
}
}