此源代码片段将把给定函数(在本例中为 main 函数)的 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());
}