]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
Merge clang trunk r338150 (just before the 7.0.0 branch point), and
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Checkers / DebugCheckers.cpp
1 //==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
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 file defines checkers that display debugging information.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ClangSACheckers.h"
15 #include "clang/Analysis/Analyses/Dominators.h"
16 #include "clang/Analysis/Analyses/LiveVariables.h"
17 #include "clang/Analysis/CallGraph.h"
18 #include "clang/StaticAnalyzer/Core/Checker.h"
19 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
21 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
22 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
24 #include "llvm/Support/Process.h"
25
26 using namespace clang;
27 using namespace ento;
28
29 //===----------------------------------------------------------------------===//
30 // DominatorsTreeDumper
31 //===----------------------------------------------------------------------===//
32
33 namespace {
34 class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
35 public:
36   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
37                         BugReporter &BR) const {
38     if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
39       DominatorTree dom;
40       dom.buildDominatorTree(*AC);
41       dom.dump();
42     }
43   }
44 };
45 }
46
47 void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
48   mgr.registerChecker<DominatorsTreeDumper>();
49 }
50
51 //===----------------------------------------------------------------------===//
52 // LiveVariablesDumper
53 //===----------------------------------------------------------------------===//
54
55 namespace {
56 class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
57 public:
58   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
59                         BugReporter &BR) const {
60     if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
61       L->dumpBlockLiveness(mgr.getSourceManager());
62     }
63   }
64 };
65 }
66
67 void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
68   mgr.registerChecker<LiveVariablesDumper>();
69 }
70
71 //===----------------------------------------------------------------------===//
72 // CFGViewer
73 //===----------------------------------------------------------------------===//
74
75 namespace {
76 class CFGViewer : public Checker<check::ASTCodeBody> {
77 public:
78   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
79                         BugReporter &BR) const {
80     if (CFG *cfg = mgr.getCFG(D)) {
81       cfg->viewCFG(mgr.getLangOpts());
82     }
83   }
84 };
85 }
86
87 void ento::registerCFGViewer(CheckerManager &mgr) {
88   mgr.registerChecker<CFGViewer>();
89 }
90
91 //===----------------------------------------------------------------------===//
92 // CFGDumper
93 //===----------------------------------------------------------------------===//
94
95 namespace {
96 class CFGDumper : public Checker<check::ASTCodeBody> {
97 public:
98   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
99                         BugReporter &BR) const {
100     PrintingPolicy Policy(mgr.getLangOpts());
101     Policy.TerseOutput = true;
102     Policy.PolishForDeclaration = true;
103     D->print(llvm::errs(), Policy);
104
105     if (CFG *cfg = mgr.getCFG(D)) {
106       cfg->dump(mgr.getLangOpts(),
107                 llvm::sys::Process::StandardErrHasColors());
108     }
109   }
110 };
111 }
112
113 void ento::registerCFGDumper(CheckerManager &mgr) {
114   mgr.registerChecker<CFGDumper>();
115 }
116
117 //===----------------------------------------------------------------------===//
118 // CallGraphViewer
119 //===----------------------------------------------------------------------===//
120
121 namespace {
122 class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
123 public:
124   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
125                     BugReporter &BR) const {
126     CallGraph CG;
127     CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
128     CG.viewGraph();
129   }
130 };
131 }
132
133 void ento::registerCallGraphViewer(CheckerManager &mgr) {
134   mgr.registerChecker<CallGraphViewer>();
135 }
136
137 //===----------------------------------------------------------------------===//
138 // CallGraphDumper
139 //===----------------------------------------------------------------------===//
140
141 namespace {
142 class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
143 public:
144   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
145                     BugReporter &BR) const {
146     CallGraph CG;
147     CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
148     CG.dump();
149   }
150 };
151 }
152
153 void ento::registerCallGraphDumper(CheckerManager &mgr) {
154   mgr.registerChecker<CallGraphDumper>();
155 }
156
157
158 //===----------------------------------------------------------------------===//
159 // ConfigDumper
160 //===----------------------------------------------------------------------===//
161
162 namespace {
163 class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
164   typedef AnalyzerOptions::ConfigTable Table;
165
166   static int compareEntry(const Table::MapEntryTy *const *LHS,
167                           const Table::MapEntryTy *const *RHS) {
168     return (*LHS)->getKey().compare((*RHS)->getKey());
169   }
170
171 public:
172   void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
173                                  AnalysisManager& mgr,
174                                  BugReporter &BR) const {
175     const Table &Config = mgr.options.Config;
176
177     SmallVector<const Table::MapEntryTy *, 32> Keys;
178     for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
179          ++I)
180       Keys.push_back(&*I);
181     llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
182
183     llvm::errs() << "[config]\n";
184     for (unsigned I = 0, E = Keys.size(); I != E; ++I)
185       llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n';
186
187     llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
188   }
189 };
190 }
191
192 void ento::registerConfigDumper(CheckerManager &mgr) {
193   mgr.registerChecker<ConfigDumper>();
194 }
195
196 //===----------------------------------------------------------------------===//
197 // ExplodedGraph Viewer
198 //===----------------------------------------------------------------------===//
199
200 namespace {
201 class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
202 public:
203   ExplodedGraphViewer() {}
204   void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
205     Eng.ViewGraph(0);
206   }
207 };
208
209 }
210
211 void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
212   mgr.registerChecker<ExplodedGraphViewer>();
213 }
214