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