1 //===--- clang-wpa.cpp - clang whole program analyzer ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
;
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."));
46 // A thin wrapper over ASTUnit implementing the TranslationUnit interface.
47 class ASTUnitTU
: public TranslationUnit
{
49 DeclReferenceMap DeclRefMap
;
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() {
73 virtual SelectorMap
&getSelectorMap() {
79 int main(int argc
, char **argv
) {
80 llvm::cl::ParseCommandLineOptions(argc
, argv
, "clang-wpa");
81 std::vector
<ASTUnit
*> ASTUnits
;
86 if (InputFilenames
.empty())
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
));
98 ASTUnits
.push_back(AST
.take());
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());
112 if (AnalyzeFunction
.empty())
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
]);
121 Entity Ent
= Entity::get(AnalyzeFunction
, Prog
);
124 llvm::tie(FD
, TU
) = Idxer
.getDefinitionFor(Ent
);
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());