clang  3.7.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 
14 #include "ClangSACheckers.h"
22 #include "llvm/Support/Process.h"
23 
24 using namespace clang;
25 using namespace ento;
26 
27 //===----------------------------------------------------------------------===//
28 // DominatorsTreeDumper
29 //===----------------------------------------------------------------------===//
30 
31 namespace {
32 class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
33 public:
34  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
35  BugReporter &BR) const {
37  DominatorTree dom;
38  dom.buildDominatorTree(*AC);
39  dom.dump();
40  }
41  }
42 };
43 }
44 
45 void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
46  mgr.registerChecker<DominatorsTreeDumper>();
47 }
48 
49 //===----------------------------------------------------------------------===//
50 // LiveVariablesDumper
51 //===----------------------------------------------------------------------===//
52 
53 namespace {
54 class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
55 public:
56  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
57  BugReporter &BR) const {
58  if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
59  L->dumpBlockLiveness(mgr.getSourceManager());
60  }
61  }
62 };
63 }
64 
65 void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
66  mgr.registerChecker<LiveVariablesDumper>();
67 }
68 
69 //===----------------------------------------------------------------------===//
70 // CFGViewer
71 //===----------------------------------------------------------------------===//
72 
73 namespace {
74 class CFGViewer : public Checker<check::ASTCodeBody> {
75 public:
76  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
77  BugReporter &BR) const {
78  if (CFG *cfg = mgr.getCFG(D)) {
79  cfg->viewCFG(mgr.getLangOpts());
80  }
81  }
82 };
83 }
84 
85 void ento::registerCFGViewer(CheckerManager &mgr) {
86  mgr.registerChecker<CFGViewer>();
87 }
88 
89 //===----------------------------------------------------------------------===//
90 // CFGDumper
91 //===----------------------------------------------------------------------===//
92 
93 namespace {
94 class CFGDumper : public Checker<check::ASTCodeBody> {
95 public:
96  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
97  BugReporter &BR) const {
98  PrintingPolicy Policy(mgr.getLangOpts());
99  Policy.TerseOutput = true;
100  Policy.PolishForDeclaration = true;
101  D->print(llvm::errs(), Policy);
102 
103  if (CFG *cfg = mgr.getCFG(D)) {
104  cfg->dump(mgr.getLangOpts(),
105  llvm::sys::Process::StandardErrHasColors());
106  }
107  }
108 };
109 }
110 
111 void ento::registerCFGDumper(CheckerManager &mgr) {
112  mgr.registerChecker<CFGDumper>();
113 }
114 
115 //===----------------------------------------------------------------------===//
116 // CallGraphViewer
117 //===----------------------------------------------------------------------===//
118 
119 namespace {
120 class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
121 public:
122  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
123  BugReporter &BR) const {
124  CallGraph CG;
125  CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
126  CG.viewGraph();
127  }
128 };
129 }
130 
131 void ento::registerCallGraphViewer(CheckerManager &mgr) {
132  mgr.registerChecker<CallGraphViewer>();
133 }
134 
135 //===----------------------------------------------------------------------===//
136 // CallGraphDumper
137 //===----------------------------------------------------------------------===//
138 
139 namespace {
140 class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
141 public:
142  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
143  BugReporter &BR) const {
144  CallGraph CG;
145  CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
146  CG.dump();
147  }
148 };
149 }
150 
151 void ento::registerCallGraphDumper(CheckerManager &mgr) {
152  mgr.registerChecker<CallGraphDumper>();
153 }
154 
155 
156 //===----------------------------------------------------------------------===//
157 // ConfigDumper
158 //===----------------------------------------------------------------------===//
159 
160 namespace {
161 class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
162  typedef AnalyzerOptions::ConfigTable Table;
163 
164  static int compareEntry(const Table::MapEntryTy *const *LHS,
165  const Table::MapEntryTy *const *RHS) {
166  return (*LHS)->getKey().compare((*RHS)->getKey());
167  }
168 
169 public:
170  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
171  AnalysisManager& mgr,
172  BugReporter &BR) const {
173  const Table &Config = mgr.options.Config;
174 
176  for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
177  ++I)
178  Keys.push_back(&*I);
179  llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
180 
181  llvm::errs() << "[config]\n";
182  for (unsigned I = 0, E = Keys.size(); I != E; ++I)
183  llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n';
184 
185  llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
186  }
187 };
188 }
189 
190 void ento::registerConfigDumper(CheckerManager &mgr) {
191  mgr.registerChecker<ConfigDumper>();
192 }
193 
194 //===----------------------------------------------------------------------===//
195 // ExplodedGraph Viewer
196 //===----------------------------------------------------------------------===//
197 
198 namespace {
199 class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
200 public:
201  ExplodedGraphViewer() {}
202  void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
203  Eng.ViewGraph(0);
204  }
205 };
206 
207 }
208 
209 void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
210  mgr.registerChecker<ExplodedGraphViewer>();
211 }
The AST-based call graph.
Definition: CallGraph.h:34
void dump()
This method dumps immediate dominators for each block, mainly used for debug purposes.
Definition: Dominators.h:91
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:35
unsigned TerseOutput
Provide a 'terse' output.
void dump() const
Definition: CallGraph.cpp:191
Concrete subclass of DominatorTreeBase for Clang This class implements the dominators tree functional...
Definition: Dominators.h:38
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
void buildDominatorTree(AnalysisDeclContext &AC)
This method builds the dominator tree for a given CFG The CFG information is passed via AnalysisDeclC...
Definition: Dominators.h:83
CFG * getCFG(Decl const *D)
CHECKER * registerChecker()
Used to register checkers.
ConfigTable Config
A key-value table of use-specified configuration values.
SourceManager & getSourceManager() override
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
void viewGraph() const
Definition: CallGraph.cpp:195
llvm::StringMap< std::string > ConfigTable
void addToCallGraph(Decl *D)
Populate the call graph with the functions in the given declaration.
Definition: CallGraph.h:53
TranslationUnitDecl - The top declaration context.
Definition: Decl.h:78
const LangOptions & getLangOpts() const
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
T * getAnalysis(Decl const *D)