3

過去 5 年間、私は Gnu Compiler Collection (gcc/g++) を使用してきたため、clang の初心者であり、C/Objective C/C++ ソース コードの制御フロー グラフを生成したいと考えています。ありがたいことに、ここここを読んで、CFG クラス関数を使用してソースレベルのステートメントの基本的なブロック表現を取得できることがわかりました: CFG::buildCFG() CFG::dump()

これは素晴らしい :) ですが、buildCFG に渡す前に関数の本体を AST 形式と ASTContext で取得する方法はまだ不明です??

特定のソースコードのCFGをclangでエクスポートする方法を示す短いスニペットをここに教えてください。

皆さん、ありがとうございました

4

2 に答える 2

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());
}
于 2019-10-16T13:35:50.443 に答える