]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[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 "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.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 // LiveStatementsDumper
73 //===----------------------------------------------------------------------===//
74
75 namespace {
76 class LiveStatementsDumper : public Checker<check::ASTCodeBody> {
77 public:
78   void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
79                         BugReporter &BR) const {
80     if (LiveVariables *L = Mgr.getAnalysis<RelaxedLiveVariables>(D))
81       L->dumpStmtLiveness(Mgr.getSourceManager());
82   }
83 };
84 }
85
86 void ento::registerLiveStatementsDumper(CheckerManager &mgr) {
87   mgr.registerChecker<LiveStatementsDumper>();
88 }
89
90 //===----------------------------------------------------------------------===//
91 // CFGViewer
92 //===----------------------------------------------------------------------===//
93
94 namespace {
95 class CFGViewer : public Checker<check::ASTCodeBody> {
96 public:
97   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
98                         BugReporter &BR) const {
99     if (CFG *cfg = mgr.getCFG(D)) {
100       cfg->viewCFG(mgr.getLangOpts());
101     }
102   }
103 };
104 }
105
106 void ento::registerCFGViewer(CheckerManager &mgr) {
107   mgr.registerChecker<CFGViewer>();
108 }
109
110 //===----------------------------------------------------------------------===//
111 // CFGDumper
112 //===----------------------------------------------------------------------===//
113
114 namespace {
115 class CFGDumper : public Checker<check::ASTCodeBody> {
116 public:
117   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
118                         BugReporter &BR) const {
119     PrintingPolicy Policy(mgr.getLangOpts());
120     Policy.TerseOutput = true;
121     Policy.PolishForDeclaration = true;
122     D->print(llvm::errs(), Policy);
123
124     if (CFG *cfg = mgr.getCFG(D)) {
125       cfg->dump(mgr.getLangOpts(),
126                 llvm::sys::Process::StandardErrHasColors());
127     }
128   }
129 };
130 }
131
132 void ento::registerCFGDumper(CheckerManager &mgr) {
133   mgr.registerChecker<CFGDumper>();
134 }
135
136 //===----------------------------------------------------------------------===//
137 // CallGraphViewer
138 //===----------------------------------------------------------------------===//
139
140 namespace {
141 class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
142 public:
143   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
144                     BugReporter &BR) const {
145     CallGraph CG;
146     CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
147     CG.viewGraph();
148   }
149 };
150 }
151
152 void ento::registerCallGraphViewer(CheckerManager &mgr) {
153   mgr.registerChecker<CallGraphViewer>();
154 }
155
156 //===----------------------------------------------------------------------===//
157 // CallGraphDumper
158 //===----------------------------------------------------------------------===//
159
160 namespace {
161 class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
162 public:
163   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
164                     BugReporter &BR) const {
165     CallGraph CG;
166     CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
167     CG.dump();
168   }
169 };
170 }
171
172 void ento::registerCallGraphDumper(CheckerManager &mgr) {
173   mgr.registerChecker<CallGraphDumper>();
174 }
175
176
177 //===----------------------------------------------------------------------===//
178 // ConfigDumper
179 //===----------------------------------------------------------------------===//
180
181 namespace {
182 class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
183   typedef AnalyzerOptions::ConfigTable Table;
184
185   static int compareEntry(const Table::MapEntryTy *const *LHS,
186                           const Table::MapEntryTy *const *RHS) {
187     return (*LHS)->getKey().compare((*RHS)->getKey());
188   }
189
190 public:
191   void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
192                                  AnalysisManager& mgr,
193                                  BugReporter &BR) const {
194     const Table &Config = mgr.options.Config;
195
196     SmallVector<const Table::MapEntryTy *, 32> Keys;
197     for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
198          ++I)
199       Keys.push_back(&*I);
200     llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
201
202     llvm::errs() << "[config]\n";
203     for (unsigned I = 0, E = Keys.size(); I != E; ++I)
204       llvm::errs() << Keys[I]->getKey() << " = "
205                    << (Keys[I]->second.empty() ? "\"\"" : Keys[I]->second)
206                    << '\n';
207
208     llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
209   }
210 };
211 }
212
213 void ento::registerConfigDumper(CheckerManager &mgr) {
214   mgr.registerChecker<ConfigDumper>();
215 }
216
217 //===----------------------------------------------------------------------===//
218 // ExplodedGraph Viewer
219 //===----------------------------------------------------------------------===//
220
221 namespace {
222 class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
223 public:
224   ExplodedGraphViewer() {}
225   void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
226     Eng.ViewGraph(0);
227   }
228 };
229
230 }
231
232 void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
233   mgr.registerChecker<ExplodedGraphViewer>();
234 }
235