1//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines a checkers that display debugging information.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ClangSACheckers.h"
15#include "clang/StaticAnalyzer/Core/Checker.h"
16#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
17#include "clang/Analysis/Analyses/LiveVariables.h"
18#include "clang/Analysis/Analyses/Dominators.h"
19#include "clang/Analysis/CallGraph.h"
20#include "llvm/Support/Process.h"
21
22using namespace clang;
23using namespace ento;
24
25//===----------------------------------------------------------------------===//
26// DominatorsTreeDumper
27//===----------------------------------------------------------------------===//
28
29namespace {
30class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
31public:
32  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
33                        BugReporter &BR) const {
34    if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
35      DominatorTree dom;
36      dom.buildDominatorTree(*AC);
37      dom.dump();
38    }
39  }
40};
41}
42
43void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
44  mgr.registerChecker<DominatorsTreeDumper>();
45}
46
47//===----------------------------------------------------------------------===//
48// LiveVariablesDumper
49//===----------------------------------------------------------------------===//
50
51namespace {
52class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
53public:
54  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
55                        BugReporter &BR) const {
56    if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
57      L->dumpBlockLiveness(mgr.getSourceManager());
58    }
59  }
60};
61}
62
63void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
64  mgr.registerChecker<LiveVariablesDumper>();
65}
66
67//===----------------------------------------------------------------------===//
68// CFGViewer
69//===----------------------------------------------------------------------===//
70
71namespace {
72class CFGViewer : public Checker<check::ASTCodeBody> {
73public:
74  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
75                        BugReporter &BR) const {
76    if (CFG *cfg = mgr.getCFG(D)) {
77      cfg->viewCFG(mgr.getLangOpts());
78    }
79  }
80};
81}
82
83void ento::registerCFGViewer(CheckerManager &mgr) {
84  mgr.registerChecker<CFGViewer>();
85}
86
87//===----------------------------------------------------------------------===//
88// CFGDumper
89//===----------------------------------------------------------------------===//
90
91namespace {
92class CFGDumper : public Checker<check::ASTCodeBody> {
93public:
94  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
95                        BugReporter &BR) const {
96    if (CFG *cfg = mgr.getCFG(D)) {
97      cfg->dump(mgr.getLangOpts(),
98                llvm::sys::Process::StandardErrHasColors());
99    }
100  }
101};
102}
103
104void ento::registerCFGDumper(CheckerManager &mgr) {
105  mgr.registerChecker<CFGDumper>();
106}
107
108//===----------------------------------------------------------------------===//
109// CallGraphViewer
110//===----------------------------------------------------------------------===//
111
112namespace {
113class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
114public:
115  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
116                    BugReporter &BR) const {
117    CallGraph CG;
118    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
119    CG.viewGraph();
120  }
121};
122}
123
124void ento::registerCallGraphViewer(CheckerManager &mgr) {
125  mgr.registerChecker<CallGraphViewer>();
126}
127
128//===----------------------------------------------------------------------===//
129// CallGraphDumper
130//===----------------------------------------------------------------------===//
131
132namespace {
133class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
134public:
135  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
136                    BugReporter &BR) const {
137    CallGraph CG;
138    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
139    CG.dump();
140  }
141};
142}
143
144void ento::registerCallGraphDumper(CheckerManager &mgr) {
145  mgr.registerChecker<CallGraphDumper>();
146}
147