自定义铿锵工具

时间:2014-11-30 11:04:08

标签: c++ clang llvm llvm-clang

我正在尝试使用此自定义clang工具。我可以毫无问题地构建它,但是当我尝试在简单示例上运行它时,我会收到很多关于using的错误。

enter image description here

当我从测试程序中删除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]);
  }
}

0 个答案:

没有答案