12d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==// 22d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 32d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 42d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 52d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 62d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 72d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 82d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 92d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 106026df1e5d518a958aef342d55a9e5d0fbdb85caJordan Rose// This file defines checkers that display debugging information. 112d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 122d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 132d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 142d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis#include "ClangSACheckers.h" 1558f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek#include "clang/Analysis/Analyses/Dominators.h" 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/Analyses/LiveVariables.h" 17196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "clang/Analysis/CallGraph.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/Checker.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 209f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" 219f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 22682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek#include "llvm/Support/Process.h" 232d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 242d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisusing namespace clang; 252d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisusing namespace ento; 262d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 272d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 2858f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek// DominatorsTreeDumper 2958f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek//===----------------------------------------------------------------------===// 3058f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek 3158f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremeneknamespace { 3258f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenekclass DominatorsTreeDumper : public Checker<check::ASTCodeBody> { 3358f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenekpublic: 3458f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 3558f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek BugReporter &BR) const { 3658f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { 3702f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks DominatorTree dom; 3802f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks dom.buildDominatorTree(*AC); 3958f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek dom.dump(); 4058f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek } 4158f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek } 4258f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek}; 4358f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek} 4458f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek 4558f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenekvoid ento::registerDominatorsTreeDumper(CheckerManager &mgr) { 4658f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek mgr.registerChecker<DominatorsTreeDumper>(); 4758f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek} 4858f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek 4958f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek//===----------------------------------------------------------------------===// 502d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// LiveVariablesDumper 512d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 522d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 532d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisnamespace { 54ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass LiveVariablesDumper : public Checker<check::ASTCodeBody> { 552d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidispublic: 562d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 572d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis BugReporter &BR) const { 58a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) { 592d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis L->dumpBlockLiveness(mgr.getSourceManager()); 602d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 612d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 622d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}; 632d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 642d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 652d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerLiveVariablesDumper(CheckerManager &mgr) { 662d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis mgr.registerChecker<LiveVariablesDumper>(); 672d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 682d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 692d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 702d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// CFGViewer 712d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 722d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 732d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisnamespace { 74ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass CFGViewer : public Checker<check::ASTCodeBody> { 752d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidispublic: 762d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 772d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis BugReporter &BR) const { 782d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis if (CFG *cfg = mgr.getCFG(D)) { 794e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie cfg->viewCFG(mgr.getLangOpts()); 802d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 812d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 822d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}; 832d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 842d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 852d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerCFGViewer(CheckerManager &mgr) { 862d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis mgr.registerChecker<CFGViewer>(); 872d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 882d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 892d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 902d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// CFGDumper 912d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 922d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 932d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisnamespace { 94ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass CFGDumper : public Checker<check::ASTCodeBody> { 952d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidispublic: 962d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 972d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis BugReporter &BR) const { 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PrintingPolicy Policy(mgr.getLangOpts()); 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Policy.TerseOutput = true; 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Policy.PolishForDeclaration = true; 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->print(llvm::errs(), Policy); 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1032d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis if (CFG *cfg = mgr.getCFG(D)) { 1044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie cfg->dump(mgr.getLangOpts(), 105682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek llvm::sys::Process::StandardErrHasColors()); 1062d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 1072d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 1082d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}; 1092d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 1102d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 1112d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerCFGDumper(CheckerManager &mgr) { 1122d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis mgr.registerChecker<CFGDumper>(); 1132d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 114196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 115196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 116196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// CallGraphViewer 117196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 118196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 119196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace { 120196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > { 121196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic: 122196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 123196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks BugReporter &BR) const { 124196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CallGraph CG; 125196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 126196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.viewGraph(); 127196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks } 128196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}; 129196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 130196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 131196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid ento::registerCallGraphViewer(CheckerManager &mgr) { 132196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks mgr.registerChecker<CallGraphViewer>(); 133196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 134196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 135196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 136196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// CallGraphDumper 137196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 138196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 139196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace { 140196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > { 141196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic: 142196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 143196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks BugReporter &BR) const { 144196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CallGraph CG; 145196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 146196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.dump(); 147196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks } 148196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}; 149196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 150196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 151196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid ento::registerCallGraphDumper(CheckerManager &mgr) { 152196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks mgr.registerChecker<CallGraphDumper>(); 153196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 15443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 15543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 15643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek//===----------------------------------------------------------------------===// 15743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek// ConfigDumper 15843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek//===----------------------------------------------------------------------===// 15943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 16043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremeneknamespace { 16143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekclass ConfigDumper : public Checker< check::EndOfTranslationUnit > { 16252e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer typedef AnalyzerOptions::ConfigTable Table; 16352e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer 164767b3d2000a00c56e1a3c19372810e2b7d66b76cBenjamin Kramer static int compareEntry(const Table::MapEntryTy *const *LHS, 165767b3d2000a00c56e1a3c19372810e2b7d66b76cBenjamin Kramer const Table::MapEntryTy *const *RHS) { 166767b3d2000a00c56e1a3c19372810e2b7d66b76cBenjamin Kramer return (*LHS)->getKey().compare((*RHS)->getKey()); 16752e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer } 16852e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer 16943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekpublic: 17043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, 17143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek AnalysisManager& mgr, 17243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek BugReporter &BR) const { 17352e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer const Table &Config = mgr.options.Config; 17443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 17552e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer SmallVector<const Table::MapEntryTy *, 32> Keys; 17652e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E; 17752e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer ++I) 17852e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer Keys.push_back(&*I); 17952e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry); 18043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 18143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek llvm::errs() << "[config]\n"; 18252e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer for (unsigned I = 0, E = Keys.size(); I != E; ++I) 18352e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n'; 18452e2d30430981289736e03d891db91af6b1397c5Benjamin Kramer 18543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n'; 18643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek } 18743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek}; 18843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek} 18943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 19043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekvoid ento::registerConfigDumper(CheckerManager &mgr) { 19143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek mgr.registerChecker<ConfigDumper>(); 19243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek} 1939f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks 1949f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks//===----------------------------------------------------------------------===// 1959f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks// ExplodedGraph Viewer 1969f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks//===----------------------------------------------------------------------===// 1979f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks 1989f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaksnamespace { 1999f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaksclass ExplodedGraphViewer : public Checker< check::EndAnalysis > { 2009f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zakspublic: 2019f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks ExplodedGraphViewer() {} 2029f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const { 2039f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks Eng.ViewGraph(0); 2049f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks } 2059f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks}; 2069f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks 2079f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks} 2089f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks 2099f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaksvoid ento::registerExplodedGraphViewer(CheckerManager &mgr) { 2109f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks mgr.registerChecker<ExplodedGraphViewer>(); 2119f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks} 212