clang  8.0.0
DebugCheckers.cpp
Go to the documentation of this file.
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 
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 
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 
The AST-based call graph.
Definition: CallGraph.h:42
void dump()
This method dumps immediate dominators for each block, mainly used for debug purposes.
Definition: Dominators.h:93
void dump() const
Definition: CallGraph.cpp:205
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
unsigned TerseOutput
Provide a &#39;terse&#39; output.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
AnalysisDeclContext contains the context data for the function or method under analysis.
Concrete subclass of DominatorTreeBase for Clang This class implements the dominators tree functional...
Definition: Dominators.h:43
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:1003
void buildDominatorTree(AnalysisDeclContext &AC)
This method builds the dominator tree for a given CFG The CFG information is passed via AnalysisDeclC...
Definition: Dominators.h:86
llvm::StringMap< std::string > ConfigTable
void viewGraph() const
Definition: CallGraph.cpp:209
Dataflow Directional Tag Classes.
void addToCallGraph(Decl *D)
Populate the call graph with the functions in the given declaration.
Definition: CallGraph.h:62
The top declaration context.
Definition: Decl.h:108