blob: 1caa3b9b68ccfa0a4708c8f1f820946d0e2d5f8e [file] [log] [blame]
Zhongxing Xu22daf792009-07-16 01:03:49 +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
Zhongxing Xudc3240c2009-07-16 01:00:25 +000015#include "clang/Basic/FileManager.h"
Daniel Dunbar31b87d82009-09-21 03:03:39 +000016#include "clang/Basic/SourceManager.h"
Zhongxing Xu65d336b2010-07-06 09:18:02 +000017#include "clang/Checker/PathSensitive/AnalysisManager.h"
18#include "clang/Checker/PathSensitive/GRExprEngine.h"
19#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
20#include "clang/Checker/Checkers/LocalCheckers.h"
Daniel Dunbar8fd57fe2009-12-03 07:20:04 +000021#include "clang/Frontend/ASTUnit.h"
Daniel Dunbar5262fda2009-12-03 01:45:44 +000022#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbar8fd57fe2009-12-03 07:20:04 +000023#include "clang/Index/CallGraph.h"
Zhongxing Xubed95e22010-07-02 11:52:15 +000024#include "clang/Index/Indexer.h"
25#include "clang/Index/TranslationUnit.h"
26#include "clang/Index/DeclReferenceMap.h"
27#include "clang/Index/SelectorMap.h"
Zhongxing Xu65d336b2010-07-06 09:18:02 +000028#include "clang/Lex/Preprocessor.h"
Douglas Gregorf45d6732010-04-06 01:25:58 +000029#include "llvm/ADT/IntrusiveRefCntPtr.h"
Zhongxing Xudc3240c2009-07-16 01:00:25 +000030#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
Zhongxing Xu81cc9552010-07-02 07:03:03 +000038static 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."));
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +000044
Zhongxing Xubed95e22010-07-02 11:52:15 +000045namespace {
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 }
Zhongxing Xu65d336b2010-07-06 09:18:02 +000060
61 virtual Preprocessor &getPreprocessor() {
62 return AST->getPreprocessor();
63 }
Zhongxing Xubed95e22010-07-02 11:52:15 +000064
65 virtual DeclReferenceMap &getDeclReferenceMap() {
66 return DeclRefMap;
67 }
68
69 virtual SelectorMap &getSelectorMap() {
70 return SelMap;
71 }
72};
73}
74
Zhongxing Xudc3240c2009-07-16 01:00:25 +000075int main(int argc, char **argv) {
76 llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
Argyrios Kyrtzidis05945452009-07-29 23:39:09 +000077 std::vector<ASTUnit*> ASTUnits;
Zhongxing Xudc3240c2009-07-16 01:00:25 +000078
Zhongxing Xu6d956df2010-07-02 06:39:46 +000079 Program Prog;
Zhongxing Xubed95e22010-07-02 11:52:15 +000080 Indexer Idxer(Prog);
Zhongxing Xu6d956df2010-07-02 06:39:46 +000081
Zhongxing Xudc3240c2009-07-16 01:00:25 +000082 if (InputFilenames.empty())
83 return 0;
84
Daniel Dunbarbb3503a2009-12-06 09:56:30 +000085 DiagnosticOptions DiagOpts;
Douglas Gregor7969f932010-04-06 04:03:12 +000086 llvm::IntrusiveRefCntPtr<Diagnostic> Diags
87 = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
Zhongxing Xudc3240c2009-07-16 01:00:25 +000088 for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
89 const std::string &InFile = InputFilenames[i];
Douglas Gregorf45d6732010-04-06 01:25:58 +000090 llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, Diags));
Daniel Dunbar5262fda2009-12-03 01:45:44 +000091 if (!AST)
Zhongxing Xudc3240c2009-07-16 01:00:25 +000092 return 1;
Zhongxing Xudc3240c2009-07-16 01:00:25 +000093
Argyrios Kyrtzidis05945452009-07-29 23:39:09 +000094 ASTUnits.push_back(AST.take());
Zhongxing Xudc3240c2009-07-16 01:00:25 +000095 }
96
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +000097 if (ViewCallGraph) {
98 llvm::OwningPtr<CallGraph> CG;
99 CG.reset(new CallGraph(Prog));
Zhongxing Xudc3240c2009-07-16 01:00:25 +0000100
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +0000101 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
102 CG->addTU(ASTUnits[i]->getASTContext());
Zhongxing Xudc3240c2009-07-16 01:00:25 +0000103
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +0000104 CG->ViewCallGraph();
105 return 0;
106 }
Zhongxing Xu81cc9552010-07-02 07:03:03 +0000107
108 if (AnalyzeFunction.empty())
109 return 0;
110
Zhongxing Xubed95e22010-07-02 11:52:15 +0000111 // Feed all ASTUnits to the Indexer.
112 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
Zhongxing Xu65d336b2010-07-06 09:18:02 +0000113 ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]);
114 Idxer.IndexAST(TU);
Zhongxing Xubed95e22010-07-02 11:52:15 +0000115 }
116
Zhongxing Xudc01a152010-07-06 05:55:13 +0000117 Entity Ent = Entity::get(AnalyzeFunction, Prog);
118 FunctionDecl *FD;
119 TranslationUnit *TU;
120 llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);
121
122 if (!FD)
123 return 0;
Zhongxing Xu65d336b2010-07-06 09:18:02 +0000124
125 // Create an analysis engine.
126 Preprocessor &PP = TU->getPreprocessor();
127
128 // Hard code options for now.
129 AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(),
130 PP.getLangOptions(), /* PathDiagnostic */ 0,
131 CreateRegionStoreManager,
Zhongxing Xuc6238d22010-07-19 01:31:21 +0000132 CreateRangeConstraintManager, &Idxer,
Zhongxing Xu65d336b2010-07-06 09:18:02 +0000133 /* MaxNodes */ 300000, /* MaxLoop */ 3,
134 /* VisualizeEG */ false, /* VisualizeEGUbi */ false,
135 /* PurgeDead */ true, /* EagerlyAssume */ false,
136 /* TrimGraph */ false, /* InlineCall */ true);
137
138 GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false,
139 AMgr.getLangOptions());
140 GRExprEngine Eng(AMgr, TF);
141
Zhongxing Xuc6238d22010-07-19 01:31:21 +0000142 Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes());
Zhongxing Xu65d336b2010-07-06 09:18:02 +0000143
Zhongxing Xu81cc9552010-07-02 07:03:03 +0000144 return 0;
Zhongxing Xudc3240c2009-07-16 01:00:25 +0000145}