157d736fdSArgyrios Kyrtzidis //==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
257d736fdSArgyrios Kyrtzidis //
357d736fdSArgyrios Kyrtzidis //                     The LLVM Compiler Infrastructure
457d736fdSArgyrios Kyrtzidis //
557d736fdSArgyrios Kyrtzidis // This file is distributed under the University of Illinois Open Source
657d736fdSArgyrios Kyrtzidis // License. See LICENSE.TXT for details.
757d736fdSArgyrios Kyrtzidis //
857d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
957d736fdSArgyrios Kyrtzidis //
1057d736fdSArgyrios Kyrtzidis //  This file defines a checkers that display debugging information.
1157d736fdSArgyrios Kyrtzidis //
1257d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
1357d736fdSArgyrios Kyrtzidis 
1457d736fdSArgyrios Kyrtzidis #include "ClangSACheckers.h"
156a5674ffSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/Checker.h"
1657d736fdSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
1757d736fdSArgyrios Kyrtzidis #include "clang/Analysis/Analyses/LiveVariables.h"
180062e749STed Kremenek #include "clang/Analysis/Analyses/Dominators.h"
19*c000e7edSAnna Zaks #include "clang/Analysis/CallGraph.h"
2072be32afSTed Kremenek #include "llvm/Support/Process.h"
2157d736fdSArgyrios Kyrtzidis 
2257d736fdSArgyrios Kyrtzidis using namespace clang;
2357d736fdSArgyrios Kyrtzidis using namespace ento;
2457d736fdSArgyrios Kyrtzidis 
2557d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
260062e749STed Kremenek // DominatorsTreeDumper
270062e749STed Kremenek //===----------------------------------------------------------------------===//
280062e749STed Kremenek 
290062e749STed Kremenek namespace {
300062e749STed Kremenek class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
310062e749STed Kremenek public:
320062e749STed Kremenek   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
330062e749STed Kremenek                         BugReporter &BR) const {
340062e749STed Kremenek     if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
3502a1fc1dSAnna Zaks       DominatorTree dom;
3602a1fc1dSAnna Zaks       dom.buildDominatorTree(*AC);
370062e749STed Kremenek       dom.dump();
380062e749STed Kremenek     }
390062e749STed Kremenek   }
400062e749STed Kremenek };
410062e749STed Kremenek }
420062e749STed Kremenek 
430062e749STed Kremenek void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
440062e749STed Kremenek   mgr.registerChecker<DominatorsTreeDumper>();
450062e749STed Kremenek }
460062e749STed Kremenek 
470062e749STed Kremenek //===----------------------------------------------------------------------===//
4857d736fdSArgyrios Kyrtzidis // LiveVariablesDumper
4957d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
5057d736fdSArgyrios Kyrtzidis 
5157d736fdSArgyrios Kyrtzidis namespace {
526a5674ffSArgyrios Kyrtzidis class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
5357d736fdSArgyrios Kyrtzidis public:
5457d736fdSArgyrios Kyrtzidis   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
5557d736fdSArgyrios Kyrtzidis                         BugReporter &BR) const {
56dccc2b22STed Kremenek     if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
5757d736fdSArgyrios Kyrtzidis       L->dumpBlockLiveness(mgr.getSourceManager());
5857d736fdSArgyrios Kyrtzidis     }
5957d736fdSArgyrios Kyrtzidis   }
6057d736fdSArgyrios Kyrtzidis };
6157d736fdSArgyrios Kyrtzidis }
6257d736fdSArgyrios Kyrtzidis 
6357d736fdSArgyrios Kyrtzidis void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
6457d736fdSArgyrios Kyrtzidis   mgr.registerChecker<LiveVariablesDumper>();
6557d736fdSArgyrios Kyrtzidis }
6657d736fdSArgyrios Kyrtzidis 
6757d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
6857d736fdSArgyrios Kyrtzidis // CFGViewer
6957d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
7057d736fdSArgyrios Kyrtzidis 
7157d736fdSArgyrios Kyrtzidis namespace {
726a5674ffSArgyrios Kyrtzidis class CFGViewer : public Checker<check::ASTCodeBody> {
7357d736fdSArgyrios Kyrtzidis public:
7457d736fdSArgyrios Kyrtzidis   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
7557d736fdSArgyrios Kyrtzidis                         BugReporter &BR) const {
7657d736fdSArgyrios Kyrtzidis     if (CFG *cfg = mgr.getCFG(D)) {
7757d736fdSArgyrios Kyrtzidis       cfg->viewCFG(mgr.getLangOptions());
7857d736fdSArgyrios Kyrtzidis     }
7957d736fdSArgyrios Kyrtzidis   }
8057d736fdSArgyrios Kyrtzidis };
8157d736fdSArgyrios Kyrtzidis }
8257d736fdSArgyrios Kyrtzidis 
8357d736fdSArgyrios Kyrtzidis void ento::registerCFGViewer(CheckerManager &mgr) {
8457d736fdSArgyrios Kyrtzidis   mgr.registerChecker<CFGViewer>();
8557d736fdSArgyrios Kyrtzidis }
8657d736fdSArgyrios Kyrtzidis 
8757d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
8857d736fdSArgyrios Kyrtzidis // CFGDumper
8957d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
9057d736fdSArgyrios Kyrtzidis 
9157d736fdSArgyrios Kyrtzidis namespace {
926a5674ffSArgyrios Kyrtzidis class CFGDumper : public Checker<check::ASTCodeBody> {
9357d736fdSArgyrios Kyrtzidis public:
9457d736fdSArgyrios Kyrtzidis   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
9557d736fdSArgyrios Kyrtzidis                         BugReporter &BR) const {
9657d736fdSArgyrios Kyrtzidis     if (CFG *cfg = mgr.getCFG(D)) {
9772be32afSTed Kremenek       cfg->dump(mgr.getLangOptions(),
9872be32afSTed Kremenek                 llvm::sys::Process::StandardErrHasColors());
9957d736fdSArgyrios Kyrtzidis     }
10057d736fdSArgyrios Kyrtzidis   }
10157d736fdSArgyrios Kyrtzidis };
10257d736fdSArgyrios Kyrtzidis }
10357d736fdSArgyrios Kyrtzidis 
10457d736fdSArgyrios Kyrtzidis void ento::registerCFGDumper(CheckerManager &mgr) {
10557d736fdSArgyrios Kyrtzidis   mgr.registerChecker<CFGDumper>();
10657d736fdSArgyrios Kyrtzidis }
107*c000e7edSAnna Zaks 
108*c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
109*c000e7edSAnna Zaks // CallGraphViewer
110*c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
111*c000e7edSAnna Zaks 
112*c000e7edSAnna Zaks namespace {
113*c000e7edSAnna Zaks class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
114*c000e7edSAnna Zaks public:
115*c000e7edSAnna Zaks   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
116*c000e7edSAnna Zaks                     BugReporter &BR) const {
117*c000e7edSAnna Zaks     CallGraph CG;
118*c000e7edSAnna Zaks     CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
119*c000e7edSAnna Zaks     CG.viewGraph();
120*c000e7edSAnna Zaks   }
121*c000e7edSAnna Zaks };
122*c000e7edSAnna Zaks }
123*c000e7edSAnna Zaks 
124*c000e7edSAnna Zaks void ento::registerCallGraphViewer(CheckerManager &mgr) {
125*c000e7edSAnna Zaks   mgr.registerChecker<CallGraphViewer>();
126*c000e7edSAnna Zaks }
127*c000e7edSAnna Zaks 
128*c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
129*c000e7edSAnna Zaks // CallGraphDumper
130*c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
131*c000e7edSAnna Zaks 
132*c000e7edSAnna Zaks namespace {
133*c000e7edSAnna Zaks class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
134*c000e7edSAnna Zaks public:
135*c000e7edSAnna Zaks   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
136*c000e7edSAnna Zaks                     BugReporter &BR) const {
137*c000e7edSAnna Zaks     CallGraph CG;
138*c000e7edSAnna Zaks     CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
139*c000e7edSAnna Zaks     CG.dump();
140*c000e7edSAnna Zaks   }
141*c000e7edSAnna Zaks };
142*c000e7edSAnna Zaks }
143*c000e7edSAnna Zaks 
144*c000e7edSAnna Zaks void ento::registerCallGraphDumper(CheckerManager &mgr) {
145*c000e7edSAnna Zaks   mgr.registerChecker<CallGraphDumper>();
146*c000e7edSAnna Zaks }
147