blob: d5cb6f845865dd670fbf4179bfe3f3d378a50952 [file] [log] [blame]
Zhongxing Xu9f077cb2010-08-25 01:15:20 +00001//===--- 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.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Basic/FileManager.h"
16#include "clang/Basic/SourceManager.h"
Ted Kremenekb4384fb2011-01-18 04:22:19 +000017#include "clang/StaticAnalyzer/PathSensitive/AnalysisManager.h"
18#include "clang/StaticAnalyzer/PathSensitive/ExprEngine.h"
19#include "clang/StaticAnalyzer/PathSensitive/TransferFuncs.h"
20#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
Zhongxing Xu9f077cb2010-08-25 01:15:20 +000021#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"
32using namespace clang;
33using namespace idx;
34
35static llvm::cl::list<std::string>
36InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
37
38static llvm::cl::opt<bool>
39ViewCallGraph("view-call-graph", llvm::cl::desc("Display the call graph."));
40
41static llvm::cl::opt<std::string>
42AnalyzeFunction("analyze-function",
43 llvm::cl::desc("Specify the entry function."));
44
45namespace {
46// A thin wrapper over ASTUnit implementing the TranslationUnit interface.
47class ASTUnitTU : public TranslationUnit {
48 ASTUnit *AST;
49 DeclReferenceMap DeclRefMap;
50 SelectorMap SelMap;
51
52public:
53 ASTUnitTU(ASTUnit *ast)
54 : AST(ast), DeclRefMap(AST->getASTContext()), SelMap(AST->getASTContext()) {
55 }
56
57 virtual ASTContext &getASTContext() {
58 return AST->getASTContext();
59 }
60
61 virtual Preprocessor &getPreprocessor() {
62 return AST->getPreprocessor();
63 }
64
65 virtual Diagnostic &getDiagnostic() {
66 return AST->getDiagnostics();
67 }
68
69 virtual DeclReferenceMap &getDeclReferenceMap() {
70 return DeclRefMap;
71 }
72
73 virtual SelectorMap &getSelectorMap() {
74 return SelMap;
75 }
76};
77}
78
79int main(int argc, char **argv) {
80 llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
81 std::vector<ASTUnit*> ASTUnits;
82
83 Program Prog;
84 Indexer Idxer(Prog);
85
86 if (InputFilenames.empty())
87 return 0;
88
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];
Ted Kremenekb4384fb2011-01-18 04:22:19 +000094 llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags,
95 FileSystemOptions(),
96 false, 0, 0, true));
Zhongxing Xu9f077cb2010-08-25 01:15:20 +000097 if (!AST)
98 return 1;
99
100 ASTUnits.push_back(AST.take());
101 }
102
103 if (ViewCallGraph) {
104 llvm::OwningPtr<CallGraph> CG;
105 CG.reset(new CallGraph(Prog));
106
107 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
108 CG->addTU(ASTUnits[i]->getASTContext());
109
110 CG->ViewCallGraph();
111 return 0;
112 }
113
114 if (AnalyzeFunction.empty())
115 return 0;
116
117 // Feed all ASTUnits to the Indexer.
118 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
119 ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]);
120 Idxer.IndexAST(TU);
121 }
122
123 Entity Ent = Entity::get(AnalyzeFunction, Prog);
124 FunctionDecl *FD;
125 TranslationUnit *TU;
126 llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);
127
128 if (!FD)
129 return 0;
130
131 // Create an analysis engine.
132 Preprocessor &PP = TU->getPreprocessor();
133
134 // Hard code options for now.
Ted Kremenekb4384fb2011-01-18 04:22:19 +0000135 using namespace clang::ento;
Zhongxing Xu9f077cb2010-08-25 01:15:20 +0000136 AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(),
137 PP.getLangOptions(), /* PathDiagnostic */ 0,
138 CreateRegionStoreManager,
139 CreateRangeConstraintManager, &Idxer,
Tom Carec88ed952010-09-14 21:35:27 +0000140 /* MaxNodes */ 300000, /* MaxVisit */ 3,
Zhongxing Xu9f077cb2010-08-25 01:15:20 +0000141 /* VisualizeEG */ false, /* VisualizeEGUbi */ false,
142 /* PurgeDead */ true, /* EagerlyAssume */ false,
143 /* TrimGraph */ false, /* InlineCall */ true,
Ted Kremenekb4384fb2011-01-18 04:22:19 +0000144 /* UseUnoptimizedCFG */ false,
145 /* addImplicitDtors */ true,
146 /* addInitializers */ false);
Zhongxing Xu9f077cb2010-08-25 01:15:20 +0000147
Argyrios Kyrtzidis1696f502010-12-22 18:53:44 +0000148 TransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false,
Zhongxing Xu9f077cb2010-08-25 01:15:20 +0000149 AMgr.getLangOptions());
Argyrios Kyrtzidis1696f502010-12-22 18:53:44 +0000150 ExprEngine Eng(AMgr, TF);
Zhongxing Xu9f077cb2010-08-25 01:15:20 +0000151
152 Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes());
153
154 return 0;
155}