如何使用Clang从源代码中提取控制流图?

时间:2016-10-05 12:31:49

标签: c clang llvm abstract-syntax-tree control-flow-graph

在过去的5年里,我一直在使用Gnu Compiler Collection(gcc / g ++),所以我是clang的新手,我想生成 C / Objective C / C ++源代码的控制流程图。 值得庆幸的是,我已阅读herehere,并发现我可以通过使用CFG类函数获取源级语句的基本块表示: CFG :: buildCFG() CFG ::转储()

这很棒:),但它的仍然不清楚对我来说如何在将它传递给buildCFG之前以AST形式和ASTContext获取函数体? / p>

有人可以在这里提供一个简短的代码,演示如何使用clang CFG导出给定的源代码?

谢谢大家

2 个答案:

答案 0 :(得分:2)

我能够使用与您上面提到的方法不同的方法生成CFG。它可能会做你需要的。注释掉以下行(TEMPORARILY):

sys::fs::remove(Filename);

来自Support / GraphWriter.cpp中的ExecGraphViewer()函数并重建clang。

然后,运行clang静态分析工具:

clang -cc1 -analyze -analyze-checker=debug.ViewCFG src_code.cpp

通常,此命令将打开图形查看器以查看您的CFG,然后在完成后将删除它为查看创建的所有.dot文件。但是,如果您对此行进行评论,即使关闭查看器,也可以将这些文件复制到其他位置。

一定要把它重新加入,否则它可能会变得非常大......

还想补充一下,Adam

帮助了我

答案 1 :(得分:0)

此源代码片段将为给定功能(在本例中为主要功能)的CFG打印到终端。

#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/CFG.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"

using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;

using namespace llvm;

DeclarationMatcher FunctionMatcher =
    functionDecl(isMain()).bind("mainFunction");

class CFGPrinter : public MatchFinder::MatchCallback {
public:
  virtual void run(const MatchFinder::MatchResult &Result) {
    if (const FunctionDecl *funcDecl =
            Result.Nodes.getNodeAs<clang::FunctionDecl>("mainFunction")) {
      ASTContext *context = Result.Context;
      Stmt *funcBody = funcDecl->getBody();
      static std::unique_ptr<CFG> sourceCFG = CFG::buildCFG(
          funcDecl, funcBody, context, clang::CFG::BuildOptions());
      auto langOpt = context->getLangOpts();
      sourceCFG->dump(langOpt, true);
    }
  }
};

// Apply a custom category to all command-line options so that they are the
// only ones displayed.
static llvm::cl::OptionCategory MyToolCategory("my-tool options");

// CommonOptionsParser declares HelpMessage with a description of the common
// command-line options related to the compilation database and input files.
// It's nice to have this help message in all tools.
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);

// A help message for this specific tool can be added afterwards.
static cl::extrahelp MoreHelp("\nMore help text...\n");

int main(int argc, const char **argv) {
  CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
  ClangTool Tool(OptionsParser.getCompilations(),
                 OptionsParser.getSourcePathList());

  CFGPrinter Printer;
  MatchFinder Finder;
  Finder.addMatcher(FunctionMatcher, &Printer);

  return Tool.run(newFrontendActionFactory(&Finder).get());
}