DebugCheckers.cpp revision 9f7ba9bd52823eb0fdb64767f2d09fb6b96b8179
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 {
982d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis    if (CFG *cfg = mgr.getCFG(D)) {
994e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      cfg->dump(mgr.getLangOpts(),
100682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek                llvm::sys::Process::StandardErrHasColors());
1012d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis    }
1022d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis  }
1032d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis};
1042d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}
1052d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis
1062d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerCFGDumper(CheckerManager &mgr) {
1072d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis  mgr.registerChecker<CFGDumper>();
1082d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}
109196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
110196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===//
111196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// CallGraphViewer
112196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===//
113196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
114196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace {
115196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
116196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic:
117196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
118196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks                    BugReporter &BR) const {
119196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    CallGraph CG;
120196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
121196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    CG.viewGraph();
122196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
123196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks};
124196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
125196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
126196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid ento::registerCallGraphViewer(CheckerManager &mgr) {
127196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  mgr.registerChecker<CallGraphViewer>();
128196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
129196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
130196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===//
131196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// CallGraphDumper
132196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===//
133196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
134196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace {
135196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
136196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic:
137196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
138196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks                    BugReporter &BR) const {
139196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    CallGraph CG;
140196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
141196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks    CG.dump();
142196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  }
143196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks};
144196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
145196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks
146196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid ento::registerCallGraphDumper(CheckerManager &mgr) {
147196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks  mgr.registerChecker<CallGraphDumper>();
148196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}
14943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
15043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
15143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek//===----------------------------------------------------------------------===//
15243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek// ConfigDumper
15343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek//===----------------------------------------------------------------------===//
15443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
15543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremeneknamespace {
15643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekclass ConfigDumper : public Checker< check::EndOfTranslationUnit > {
15743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekpublic:
15843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
15943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek                                 AnalysisManager& mgr,
16043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek                                 BugReporter &BR) const {
16143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
16243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    const AnalyzerOptions::ConfigTable &Config = mgr.options.Config;
16343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    AnalyzerOptions::ConfigTable::const_iterator I =
16443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek      Config.begin(), E = Config.end();
16543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
16643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    std::vector<StringRef> Keys;
16743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    for (; I != E ; ++I) { Keys.push_back(I->getKey()); }
16843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    sort(Keys.begin(), Keys.end());
16943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
17043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    llvm::errs() << "[config]\n";
17143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    for (unsigned i = 0, n = Keys.size(); i < n ; ++i) {
17243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek      StringRef Key = Keys[i];
17343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek      I = Config.find(Key);
17443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek      llvm::errs() << Key << " = " << I->second << '\n';
17543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    }
17643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek    llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
17743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek  }
17843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek};
17943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek}
18043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek
18143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekvoid ento::registerConfigDumper(CheckerManager &mgr) {
18243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek  mgr.registerChecker<ConfigDumper>();
18343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek}
1849f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks
1859f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks//===----------------------------------------------------------------------===//
1869f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks// ExplodedGraph Viewer
1879f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks//===----------------------------------------------------------------------===//
1889f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks
1899f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaksnamespace {
1909f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaksclass ExplodedGraphViewer : public Checker< check::EndAnalysis > {
1919f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zakspublic:
1929f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks  ExplodedGraphViewer() {}
1939f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks  void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
1949f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks    Eng.ViewGraph(0);
1959f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks  }
1969f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks};
1979f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks
1989f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks}
1999f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks
2009f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaksvoid ento::registerExplodedGraphViewer(CheckerManager &mgr) {
2019f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks  mgr.registerChecker<ExplodedGraphViewer>();
2029f7ba9bd52823eb0fdb64767f2d09fb6b96b8179Anna Zaks}
203