1218887Sdim//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10251662Sdim// This file defines checkers that display debugging information. 11218887Sdim// 12218887Sdim//===----------------------------------------------------------------------===// 13218887Sdim 14218887Sdim#include "ClangSACheckers.h" 15249423Sdim#include "clang/Analysis/Analyses/Dominators.h" 16249423Sdim#include "clang/Analysis/Analyses/LiveVariables.h" 17249423Sdim#include "clang/Analysis/CallGraph.h" 18221345Sdim#include "clang/StaticAnalyzer/Core/Checker.h" 19218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 20263508Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" 21263508Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 22234353Sdim#include "llvm/Support/Process.h" 23218887Sdim 24218887Sdimusing namespace clang; 25218887Sdimusing namespace ento; 26218887Sdim 27218887Sdim//===----------------------------------------------------------------------===// 28234353Sdim// DominatorsTreeDumper 29234353Sdim//===----------------------------------------------------------------------===// 30234353Sdim 31234353Sdimnamespace { 32234353Sdimclass DominatorsTreeDumper : public Checker<check::ASTCodeBody> { 33234353Sdimpublic: 34234353Sdim void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 35234353Sdim BugReporter &BR) const { 36234353Sdim if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { 37234353Sdim DominatorTree dom; 38234353Sdim dom.buildDominatorTree(*AC); 39234353Sdim dom.dump(); 40234353Sdim } 41234353Sdim } 42234353Sdim}; 43234353Sdim} 44234353Sdim 45234353Sdimvoid ento::registerDominatorsTreeDumper(CheckerManager &mgr) { 46234353Sdim mgr.registerChecker<DominatorsTreeDumper>(); 47234353Sdim} 48234353Sdim 49234353Sdim//===----------------------------------------------------------------------===// 50218887Sdim// LiveVariablesDumper 51218887Sdim//===----------------------------------------------------------------------===// 52218887Sdim 53218887Sdimnamespace { 54221345Sdimclass LiveVariablesDumper : public Checker<check::ASTCodeBody> { 55218887Sdimpublic: 56218887Sdim void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 57218887Sdim BugReporter &BR) const { 58226633Sdim if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) { 59218887Sdim L->dumpBlockLiveness(mgr.getSourceManager()); 60218887Sdim } 61218887Sdim } 62218887Sdim}; 63218887Sdim} 64218887Sdim 65218887Sdimvoid ento::registerLiveVariablesDumper(CheckerManager &mgr) { 66218887Sdim mgr.registerChecker<LiveVariablesDumper>(); 67218887Sdim} 68218887Sdim 69218887Sdim//===----------------------------------------------------------------------===// 70218887Sdim// CFGViewer 71218887Sdim//===----------------------------------------------------------------------===// 72218887Sdim 73218887Sdimnamespace { 74221345Sdimclass CFGViewer : public Checker<check::ASTCodeBody> { 75218887Sdimpublic: 76218887Sdim void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 77218887Sdim BugReporter &BR) const { 78218887Sdim if (CFG *cfg = mgr.getCFG(D)) { 79234353Sdim cfg->viewCFG(mgr.getLangOpts()); 80218887Sdim } 81218887Sdim } 82218887Sdim}; 83218887Sdim} 84218887Sdim 85218887Sdimvoid ento::registerCFGViewer(CheckerManager &mgr) { 86218887Sdim mgr.registerChecker<CFGViewer>(); 87218887Sdim} 88218887Sdim 89218887Sdim//===----------------------------------------------------------------------===// 90218887Sdim// CFGDumper 91218887Sdim//===----------------------------------------------------------------------===// 92218887Sdim 93218887Sdimnamespace { 94221345Sdimclass CFGDumper : public Checker<check::ASTCodeBody> { 95218887Sdimpublic: 96218887Sdim void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 97218887Sdim BugReporter &BR) const { 98218887Sdim if (CFG *cfg = mgr.getCFG(D)) { 99234353Sdim cfg->dump(mgr.getLangOpts(), 100234353Sdim llvm::sys::Process::StandardErrHasColors()); 101218887Sdim } 102218887Sdim } 103218887Sdim}; 104218887Sdim} 105218887Sdim 106218887Sdimvoid ento::registerCFGDumper(CheckerManager &mgr) { 107218887Sdim mgr.registerChecker<CFGDumper>(); 108218887Sdim} 109234353Sdim 110234353Sdim//===----------------------------------------------------------------------===// 111234353Sdim// CallGraphViewer 112234353Sdim//===----------------------------------------------------------------------===// 113234353Sdim 114234353Sdimnamespace { 115234353Sdimclass CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > { 116234353Sdimpublic: 117234353Sdim void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 118234353Sdim BugReporter &BR) const { 119234353Sdim CallGraph CG; 120234353Sdim CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 121234353Sdim CG.viewGraph(); 122234353Sdim } 123234353Sdim}; 124234353Sdim} 125234353Sdim 126234353Sdimvoid ento::registerCallGraphViewer(CheckerManager &mgr) { 127234353Sdim mgr.registerChecker<CallGraphViewer>(); 128234353Sdim} 129234353Sdim 130234353Sdim//===----------------------------------------------------------------------===// 131234353Sdim// CallGraphDumper 132234353Sdim//===----------------------------------------------------------------------===// 133234353Sdim 134234353Sdimnamespace { 135234353Sdimclass CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > { 136234353Sdimpublic: 137234353Sdim void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 138234353Sdim BugReporter &BR) const { 139234353Sdim CallGraph CG; 140234353Sdim CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 141234353Sdim CG.dump(); 142234353Sdim } 143234353Sdim}; 144234353Sdim} 145234353Sdim 146234353Sdimvoid ento::registerCallGraphDumper(CheckerManager &mgr) { 147234353Sdim mgr.registerChecker<CallGraphDumper>(); 148234353Sdim} 149243830Sdim 150243830Sdim 151243830Sdim//===----------------------------------------------------------------------===// 152243830Sdim// ConfigDumper 153243830Sdim//===----------------------------------------------------------------------===// 154243830Sdim 155243830Sdimnamespace { 156243830Sdimclass ConfigDumper : public Checker< check::EndOfTranslationUnit > { 157263508Sdim typedef AnalyzerOptions::ConfigTable Table; 158263508Sdim 159263508Sdim static int compareEntry(const Table::MapEntryTy *const *LHS, 160263508Sdim const Table::MapEntryTy *const *RHS) { 161263508Sdim return (*LHS)->getKey().compare((*RHS)->getKey()); 162263508Sdim } 163263508Sdim 164243830Sdimpublic: 165243830Sdim void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, 166243830Sdim AnalysisManager& mgr, 167243830Sdim BugReporter &BR) const { 168263508Sdim const Table &Config = mgr.options.Config; 169243830Sdim 170263508Sdim SmallVector<const Table::MapEntryTy *, 32> Keys; 171263508Sdim for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E; 172263508Sdim ++I) 173263508Sdim Keys.push_back(&*I); 174263508Sdim llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry); 175243830Sdim 176243830Sdim llvm::errs() << "[config]\n"; 177263508Sdim for (unsigned I = 0, E = Keys.size(); I != E; ++I) 178263508Sdim llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n'; 179263508Sdim 180243830Sdim llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n'; 181243830Sdim } 182243830Sdim}; 183243830Sdim} 184243830Sdim 185243830Sdimvoid ento::registerConfigDumper(CheckerManager &mgr) { 186243830Sdim mgr.registerChecker<ConfigDumper>(); 187243830Sdim} 188263508Sdim 189263508Sdim//===----------------------------------------------------------------------===// 190263508Sdim// ExplodedGraph Viewer 191263508Sdim//===----------------------------------------------------------------------===// 192263508Sdim 193263508Sdimnamespace { 194263508Sdimclass ExplodedGraphViewer : public Checker< check::EndAnalysis > { 195263508Sdimpublic: 196263508Sdim ExplodedGraphViewer() {} 197263508Sdim void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const { 198263508Sdim Eng.ViewGraph(0); 199263508Sdim } 200263508Sdim}; 201263508Sdim 202263508Sdim} 203263508Sdim 204263508Sdimvoid ento::registerExplodedGraphViewer(CheckerManager &mgr) { 205263508Sdim mgr.registerChecker<ExplodedGraphViewer>(); 206263508Sdim} 207