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// 10252723Sdim// This file defines checkers that display debugging information. 11218887Sdim// 12218887Sdim//===----------------------------------------------------------------------===// 13218887Sdim 14218887Sdim#include "ClangSACheckers.h" 15252723Sdim#include "clang/Analysis/Analyses/Dominators.h" 16252723Sdim#include "clang/Analysis/Analyses/LiveVariables.h" 17252723Sdim#include "clang/Analysis/CallGraph.h" 18221345Sdim#include "clang/StaticAnalyzer/Core/Checker.h" 19218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 20263509Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" 21263509Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 22235633Sdim#include "llvm/Support/Process.h" 23218887Sdim 24218887Sdimusing namespace clang; 25218887Sdimusing namespace ento; 26218887Sdim 27218887Sdim//===----------------------------------------------------------------------===// 28235633Sdim// DominatorsTreeDumper 29235633Sdim//===----------------------------------------------------------------------===// 30235633Sdim 31235633Sdimnamespace { 32235633Sdimclass DominatorsTreeDumper : public Checker<check::ASTCodeBody> { 33235633Sdimpublic: 34235633Sdim void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 35235633Sdim BugReporter &BR) const { 36235633Sdim if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { 37235633Sdim DominatorTree dom; 38235633Sdim dom.buildDominatorTree(*AC); 39235633Sdim dom.dump(); 40235633Sdim } 41235633Sdim } 42235633Sdim}; 43235633Sdim} 44235633Sdim 45235633Sdimvoid ento::registerDominatorsTreeDumper(CheckerManager &mgr) { 46235633Sdim mgr.registerChecker<DominatorsTreeDumper>(); 47235633Sdim} 48235633Sdim 49235633Sdim//===----------------------------------------------------------------------===// 50218887Sdim// LiveVariablesDumper 51218887Sdim//===----------------------------------------------------------------------===// 52218887Sdim 53218887Sdimnamespace { 54221345Sdimclass LiveVariablesDumper : public Checker<check::ASTCodeBody> { 55218887Sdimpublic: 56218887Sdim void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 57218887Sdim BugReporter &BR) const { 58226890Sdim 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)) { 79235633Sdim 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)) { 99235633Sdim cfg->dump(mgr.getLangOpts(), 100235633Sdim llvm::sys::Process::StandardErrHasColors()); 101218887Sdim } 102218887Sdim } 103218887Sdim}; 104218887Sdim} 105218887Sdim 106218887Sdimvoid ento::registerCFGDumper(CheckerManager &mgr) { 107218887Sdim mgr.registerChecker<CFGDumper>(); 108218887Sdim} 109235633Sdim 110235633Sdim//===----------------------------------------------------------------------===// 111235633Sdim// CallGraphViewer 112235633Sdim//===----------------------------------------------------------------------===// 113235633Sdim 114235633Sdimnamespace { 115235633Sdimclass CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > { 116235633Sdimpublic: 117235633Sdim void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 118235633Sdim BugReporter &BR) const { 119235633Sdim CallGraph CG; 120235633Sdim CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 121235633Sdim CG.viewGraph(); 122235633Sdim } 123235633Sdim}; 124235633Sdim} 125235633Sdim 126235633Sdimvoid ento::registerCallGraphViewer(CheckerManager &mgr) { 127235633Sdim mgr.registerChecker<CallGraphViewer>(); 128235633Sdim} 129235633Sdim 130235633Sdim//===----------------------------------------------------------------------===// 131235633Sdim// CallGraphDumper 132235633Sdim//===----------------------------------------------------------------------===// 133235633Sdim 134235633Sdimnamespace { 135235633Sdimclass CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > { 136235633Sdimpublic: 137235633Sdim void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 138235633Sdim BugReporter &BR) const { 139235633Sdim CallGraph CG; 140235633Sdim CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 141235633Sdim CG.dump(); 142235633Sdim } 143235633Sdim}; 144235633Sdim} 145235633Sdim 146235633Sdimvoid ento::registerCallGraphDumper(CheckerManager &mgr) { 147235633Sdim mgr.registerChecker<CallGraphDumper>(); 148235633Sdim} 149245431Sdim 150245431Sdim 151245431Sdim//===----------------------------------------------------------------------===// 152245431Sdim// ConfigDumper 153245431Sdim//===----------------------------------------------------------------------===// 154245431Sdim 155245431Sdimnamespace { 156245431Sdimclass ConfigDumper : public Checker< check::EndOfTranslationUnit > { 157263509Sdim typedef AnalyzerOptions::ConfigTable Table; 158263509Sdim 159263509Sdim static int compareEntry(const Table::MapEntryTy *const *LHS, 160263509Sdim const Table::MapEntryTy *const *RHS) { 161263509Sdim return (*LHS)->getKey().compare((*RHS)->getKey()); 162263509Sdim } 163263509Sdim 164245431Sdimpublic: 165245431Sdim void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, 166245431Sdim AnalysisManager& mgr, 167245431Sdim BugReporter &BR) const { 168263509Sdim const Table &Config = mgr.options.Config; 169245431Sdim 170263509Sdim SmallVector<const Table::MapEntryTy *, 32> Keys; 171263509Sdim for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E; 172263509Sdim ++I) 173263509Sdim Keys.push_back(&*I); 174263509Sdim llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry); 175245431Sdim 176245431Sdim llvm::errs() << "[config]\n"; 177263509Sdim for (unsigned I = 0, E = Keys.size(); I != E; ++I) 178263509Sdim llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n'; 179263509Sdim 180245431Sdim llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n'; 181245431Sdim } 182245431Sdim}; 183245431Sdim} 184245431Sdim 185245431Sdimvoid ento::registerConfigDumper(CheckerManager &mgr) { 186245431Sdim mgr.registerChecker<ConfigDumper>(); 187245431Sdim} 188263509Sdim 189263509Sdim//===----------------------------------------------------------------------===// 190263509Sdim// ExplodedGraph Viewer 191263509Sdim//===----------------------------------------------------------------------===// 192263509Sdim 193263509Sdimnamespace { 194263509Sdimclass ExplodedGraphViewer : public Checker< check::EndAnalysis > { 195263509Sdimpublic: 196263509Sdim ExplodedGraphViewer() {} 197263509Sdim void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const { 198263509Sdim Eng.ViewGraph(0); 199263509Sdim } 200263509Sdim}; 201263509Sdim 202263509Sdim} 203263509Sdim 204263509Sdimvoid ento::registerExplodedGraphViewer(CheckerManager &mgr) { 205263509Sdim mgr.registerChecker<ExplodedGraphViewer>(); 206263509Sdim} 207