blob: bfac398532a2603bca572e6ee63bd977ca1b90dd [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"
Daniel Dunbar8fd57fe2009-12-03 07:20:04 +000017#include "clang/Frontend/ASTUnit.h"
Daniel Dunbar5262fda2009-12-03 01:45:44 +000018#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbar8fd57fe2009-12-03 07:20:04 +000019#include "clang/Index/CallGraph.h"
Zhongxing Xubed95e22010-07-02 11:52:15 +000020#include "clang/Index/Indexer.h"
21#include "clang/Index/TranslationUnit.h"
22#include "clang/Index/DeclReferenceMap.h"
23#include "clang/Index/SelectorMap.h"
Douglas Gregorf45d6732010-04-06 01:25:58 +000024#include "llvm/ADT/IntrusiveRefCntPtr.h"
Zhongxing Xudc3240c2009-07-16 01:00:25 +000025#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/raw_ostream.h"
27using namespace clang;
28using namespace idx;
29
30static llvm::cl::list<std::string>
31InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
32
Zhongxing Xu81cc9552010-07-02 07:03:03 +000033static llvm::cl::opt<bool>
34ViewCallGraph("view-call-graph", llvm::cl::desc("Display the call graph."));
35
36static llvm::cl::opt<std::string>
37AnalyzeFunction("analyze-function",
38 llvm::cl::desc("Specify the entry function."));
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +000039
Zhongxing Xubed95e22010-07-02 11:52:15 +000040namespace {
41// A thin wrapper over ASTUnit implementing the TranslationUnit interface.
42class ASTUnitTU : public TranslationUnit {
43 ASTUnit *AST;
44 DeclReferenceMap DeclRefMap;
45 SelectorMap SelMap;
46
47public:
48 ASTUnitTU(ASTUnit *ast)
49 : AST(ast), DeclRefMap(AST->getASTContext()), SelMap(AST->getASTContext()) {
50 }
51
52 virtual ASTContext &getASTContext() {
53 return AST->getASTContext();
54 }
55
56 virtual DeclReferenceMap &getDeclReferenceMap() {
57 return DeclRefMap;
58 }
59
60 virtual SelectorMap &getSelectorMap() {
61 return SelMap;
62 }
63};
64}
65
Zhongxing Xudc3240c2009-07-16 01:00:25 +000066int main(int argc, char **argv) {
67 llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
Argyrios Kyrtzidis05945452009-07-29 23:39:09 +000068 std::vector<ASTUnit*> ASTUnits;
Zhongxing Xudc3240c2009-07-16 01:00:25 +000069
Zhongxing Xu6d956df2010-07-02 06:39:46 +000070 Program Prog;
Zhongxing Xubed95e22010-07-02 11:52:15 +000071 Indexer Idxer(Prog);
Zhongxing Xu6d956df2010-07-02 06:39:46 +000072
Zhongxing Xudc3240c2009-07-16 01:00:25 +000073 if (InputFilenames.empty())
74 return 0;
75
Daniel Dunbarbb3503a2009-12-06 09:56:30 +000076 DiagnosticOptions DiagOpts;
Douglas Gregor7969f932010-04-06 04:03:12 +000077 llvm::IntrusiveRefCntPtr<Diagnostic> Diags
78 = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
Zhongxing Xudc3240c2009-07-16 01:00:25 +000079 for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
80 const std::string &InFile = InputFilenames[i];
Douglas Gregorf45d6732010-04-06 01:25:58 +000081 llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, Diags));
Daniel Dunbar5262fda2009-12-03 01:45:44 +000082 if (!AST)
Zhongxing Xudc3240c2009-07-16 01:00:25 +000083 return 1;
Zhongxing Xudc3240c2009-07-16 01:00:25 +000084
Argyrios Kyrtzidis05945452009-07-29 23:39:09 +000085 ASTUnits.push_back(AST.take());
Zhongxing Xudc3240c2009-07-16 01:00:25 +000086 }
87
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +000088 if (ViewCallGraph) {
89 llvm::OwningPtr<CallGraph> CG;
90 CG.reset(new CallGraph(Prog));
Zhongxing Xudc3240c2009-07-16 01:00:25 +000091
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +000092 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
93 CG->addTU(ASTUnits[i]->getASTContext());
Zhongxing Xudc3240c2009-07-16 01:00:25 +000094
Zhongxing Xu9b80ceb2010-07-02 06:58:30 +000095 CG->ViewCallGraph();
96 return 0;
97 }
Zhongxing Xu81cc9552010-07-02 07:03:03 +000098
99 if (AnalyzeFunction.empty())
100 return 0;
101
Zhongxing Xubed95e22010-07-02 11:52:15 +0000102 // Feed all ASTUnits to the Indexer.
103 for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
104 ASTUnitTU TU(ASTUnits[i]);
105 Idxer.IndexAST(&TU);
106 }
107
Zhongxing Xudc01a152010-07-06 05:55:13 +0000108 Entity Ent = Entity::get(AnalyzeFunction, Prog);
109 FunctionDecl *FD;
110 TranslationUnit *TU;
111 llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);
112
113 if (!FD)
114 return 0;
Zhongxing Xu81cc9552010-07-02 07:03:03 +0000115 return 0;
Zhongxing Xudc3240c2009-07-16 01:00:25 +0000116}