[analyzer] Refactoring: include/clang/Checker -> include/clang/GR
[clang.git] / examples / wpa / clang-wpa.cpp
blob45e889e170b800a04d7ac9b19b30941b14c0115e
1 //===--- clang-wpa.cpp - clang whole program analyzer ---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This tool reads a sequence of precompiled AST files, and do various
11 // cross translation unit analyses.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "clang/GR/PathSensitive/AnalysisManager.h"
18 #include "clang/GR/PathSensitive/GRExprEngine.h"
19 #include "clang/GR/PathSensitive/GRTransferFuncs.h"
20 #include "clang/GR/Checkers/LocalCheckers.h"
21 #include "clang/Frontend/ASTUnit.h"
22 #include "clang/Frontend/CompilerInstance.h"
23 #include "clang/Index/CallGraph.h"
24 #include "clang/Index/Indexer.h"
25 #include "clang/Index/TranslationUnit.h"
26 #include "clang/Index/DeclReferenceMap.h"
27 #include "clang/Index/SelectorMap.h"
28 #include "clang/Lex/Preprocessor.h"
29 #include "llvm/ADT/IntrusiveRefCntPtr.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/raw_ostream.h"
32 using namespace clang;
33 using namespace idx;
35 static llvm::cl::list<std::string>
36 InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
38 static llvm::cl::opt<bool>
39 ViewCallGraph("view-call-graph", llvm::cl::desc("Display the call graph."));
41 static llvm::cl::opt<std::string>
42 AnalyzeFunction("analyze-function",
43 llvm::cl::desc("Specify the entry function."));
45 namespace {
46 // A thin wrapper over ASTUnit implementing the TranslationUnit interface.
47 class ASTUnitTU : public TranslationUnit {
48 ASTUnit *AST;
49 DeclReferenceMap DeclRefMap;
50 SelectorMap SelMap;
52 public:
53 ASTUnitTU(ASTUnit *ast)
54 : AST(ast), DeclRefMap(AST->getASTContext()), SelMap(AST->getASTContext()) {
57 virtual ASTContext &getASTContext() {
58 return AST->getASTContext();
61 virtual Preprocessor &getPreprocessor() {
62 return AST->getPreprocessor();
65 virtual Diagnostic &getDiagnostic() {
66 return AST->getDiagnostics();
69 virtual DeclReferenceMap &getDeclReferenceMap() {
70 return DeclRefMap;
73 virtual SelectorMap &getSelectorMap() {
74 return SelMap;
79 int main(int argc, char **argv) {
80 llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
81 std::vector<ASTUnit*> ASTUnits;
83 Program Prog;
84 Indexer Idxer(Prog);
86 if (InputFilenames.empty())
87 return 0;
89 DiagnosticOptions DiagOpts;
90 llvm::IntrusiveRefCntPtr<Diagnostic> Diags
91 = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
92 for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
93 const std::string &InFile = InputFilenames[i];
94 llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags));
95 if (!AST)
96 return 1;
98 ASTUnits.push_back(AST.take());
101 if (ViewCallGraph) {
102 llvm::OwningPtr<CallGraph> CG;
103 CG.reset(new CallGraph(Prog));
105 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
106 CG->addTU(ASTUnits[i]->getASTContext());
108 CG->ViewCallGraph();
109 return 0;
112 if (AnalyzeFunction.empty())
113 return 0;
115 // Feed all ASTUnits to the Indexer.
116 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
117 ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]);
118 Idxer.IndexAST(TU);
121 Entity Ent = Entity::get(AnalyzeFunction, Prog);
122 FunctionDecl *FD;
123 TranslationUnit *TU;
124 llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);
126 if (!FD)
127 return 0;
129 // Create an analysis engine.
130 Preprocessor &PP = TU->getPreprocessor();
132 // Hard code options for now.
133 AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(),
134 PP.getLangOptions(), /* PathDiagnostic */ 0,
135 CreateRegionStoreManager,
136 CreateRangeConstraintManager, &Idxer,
137 /* MaxNodes */ 300000, /* MaxVisit */ 3,
138 /* VisualizeEG */ false, /* VisualizeEGUbi */ false,
139 /* PurgeDead */ true, /* EagerlyAssume */ false,
140 /* TrimGraph */ false, /* InlineCall */ true,
141 /* UseUnoptimizedCFG */ false);
143 GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false,
144 AMgr.getLangOptions());
145 GRExprEngine Eng(AMgr, TF);
147 Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes());
149 return 0;