DebugCheckers.cpp revision 9f7ba9bd52823eb0fdb64767f2d09fb6b96b8179
1391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==// 2391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// 3391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// The LLVM Compiler Infrastructure 4391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// 5391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// This file is distributed under the University of Illinois Open Source 6391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// License. See LICENSE.TXT for details. 7391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// 8391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//===----------------------------------------------------------------------===// 9391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// 10391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// This file defines checkers that display debugging information. 11391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// 12391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//===----------------------------------------------------------------------===// 13391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 14391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "ClangSACheckers.h" 15391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/Analysis/Analyses/Dominators.h" 16391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/Analysis/Analyses/LiveVariables.h" 17391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/Analysis/CallGraph.h" 18391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/StaticAnalyzer/Core/Checker.h" 19391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 20391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" 21391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 22391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer#include "llvm/Support/Process.h" 23391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 24391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramerusing namespace clang; 25391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramerusing namespace ento; 26391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 27391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//===----------------------------------------------------------------------===// 28391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// DominatorsTreeDumper 29391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//===----------------------------------------------------------------------===// 30391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 31391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramernamespace { 32391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramerclass DominatorsTreeDumper : public Checker<check::ASTCodeBody> { 33391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramerpublic: 34391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 35391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer BugReporter &BR) const { 36391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { 37391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer DominatorTree dom; 38391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer dom.buildDominatorTree(*AC); 39391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer dom.dump(); 40391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer } 41391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer } 42391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer}; 43391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer} 44391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 45391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramervoid ento::registerDominatorsTreeDumper(CheckerManager &mgr) { 46391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer mgr.registerChecker<DominatorsTreeDumper>(); 47391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer} 48391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 49391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//===----------------------------------------------------------------------===// 50391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer// LiveVariablesDumper 51391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer//===----------------------------------------------------------------------===// 52391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 53391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramernamespace { 54391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramerclass LiveVariablesDumper : public Checker<check::ASTCodeBody> { 55391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramerpublic: 56391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 57391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer BugReporter &BR) const { 58391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) { 59391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer L->dumpBlockLiveness(mgr.getSourceManager()); 60391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer } 61ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer } 62ed9e442cf098663ce213cb16778b44be466b441fBenjamin Kramer}; 63391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer} 64391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 65391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramervoid ento::registerLiveVariablesDumper(CheckerManager &mgr) { 66391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer mgr.registerChecker<LiveVariablesDumper>(); 67391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer} 68391271f3bbcec02e0da26d7c246bfabff5cb4ddfBenjamin Kramer 69//===----------------------------------------------------------------------===// 70// CFGViewer 71//===----------------------------------------------------------------------===// 72 73namespace { 74class CFGViewer : public Checker<check::ASTCodeBody> { 75public: 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 85void ento::registerCFGViewer(CheckerManager &mgr) { 86 mgr.registerChecker<CFGViewer>(); 87} 88 89//===----------------------------------------------------------------------===// 90// CFGDumper 91//===----------------------------------------------------------------------===// 92 93namespace { 94class CFGDumper : public Checker<check::ASTCodeBody> { 95public: 96 void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 97 BugReporter &BR) const { 98 if (CFG *cfg = mgr.getCFG(D)) { 99 cfg->dump(mgr.getLangOpts(), 100 llvm::sys::Process::StandardErrHasColors()); 101 } 102 } 103}; 104} 105 106void ento::registerCFGDumper(CheckerManager &mgr) { 107 mgr.registerChecker<CFGDumper>(); 108} 109 110//===----------------------------------------------------------------------===// 111// CallGraphViewer 112//===----------------------------------------------------------------------===// 113 114namespace { 115class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > { 116public: 117 void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 118 BugReporter &BR) const { 119 CallGraph CG; 120 CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 121 CG.viewGraph(); 122 } 123}; 124} 125 126void ento::registerCallGraphViewer(CheckerManager &mgr) { 127 mgr.registerChecker<CallGraphViewer>(); 128} 129 130//===----------------------------------------------------------------------===// 131// CallGraphDumper 132//===----------------------------------------------------------------------===// 133 134namespace { 135class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > { 136public: 137 void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 138 BugReporter &BR) const { 139 CallGraph CG; 140 CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 141 CG.dump(); 142 } 143}; 144} 145 146void ento::registerCallGraphDumper(CheckerManager &mgr) { 147 mgr.registerChecker<CallGraphDumper>(); 148} 149 150 151//===----------------------------------------------------------------------===// 152// ConfigDumper 153//===----------------------------------------------------------------------===// 154 155namespace { 156class ConfigDumper : public Checker< check::EndOfTranslationUnit > { 157public: 158 void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, 159 AnalysisManager& mgr, 160 BugReporter &BR) const { 161 162 const AnalyzerOptions::ConfigTable &Config = mgr.options.Config; 163 AnalyzerOptions::ConfigTable::const_iterator I = 164 Config.begin(), E = Config.end(); 165 166 std::vector<StringRef> Keys; 167 for (; I != E ; ++I) { Keys.push_back(I->getKey()); } 168 sort(Keys.begin(), Keys.end()); 169 170 llvm::errs() << "[config]\n"; 171 for (unsigned i = 0, n = Keys.size(); i < n ; ++i) { 172 StringRef Key = Keys[i]; 173 I = Config.find(Key); 174 llvm::errs() << Key << " = " << I->second << '\n'; 175 } 176 llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n'; 177 } 178}; 179} 180 181void ento::registerConfigDumper(CheckerManager &mgr) { 182 mgr.registerChecker<ConfigDumper>(); 183} 184 185//===----------------------------------------------------------------------===// 186// ExplodedGraph Viewer 187//===----------------------------------------------------------------------===// 188 189namespace { 190class ExplodedGraphViewer : public Checker< check::EndAnalysis > { 191public: 192 ExplodedGraphViewer() {} 193 void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const { 194 Eng.ViewGraph(0); 195 } 196}; 197 198} 199 200void ento::registerExplodedGraphViewer(CheckerManager &mgr) { 201 mgr.registerChecker<ExplodedGraphViewer>(); 202} 203