blob: 29b4a637cda4be3914fdd6b3432e8e7d85e10069 [file] [log] [blame]
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +00001//==- 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"
Chandler Carruth55fc8732012-12-04 09:13:33 +000015#include "clang/Analysis/Analyses/Dominators.h"
16#include "clang/Analysis/Analyses/LiveVariables.h"
17#include "clang/Analysis/CallGraph.h"
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000018#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000019#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
Ted Kremenek682060c2011-12-22 23:33:52 +000020#include "llvm/Support/Process.h"
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000021
22using namespace clang;
23using namespace ento;
24
25//===----------------------------------------------------------------------===//
Ted Kremenek58f6f1e2011-10-25 00:25:24 +000026// 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)) {
Anna Zaks02f34c52011-12-05 21:33:11 +000035 DominatorTree dom;
36 dom.buildDominatorTree(*AC);
Ted Kremenek58f6f1e2011-10-25 00:25:24 +000037 dom.dump();
38 }
39 }
40};
41}
42
43void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
44 mgr.registerChecker<DominatorsTreeDumper>();
45}
46
47//===----------------------------------------------------------------------===//
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000048// LiveVariablesDumper
49//===----------------------------------------------------------------------===//
50
51namespace {
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000052class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000053public:
54 void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
55 BugReporter &BR) const {
Ted Kremeneka5937bb2011-10-07 22:21:02 +000056 if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000057 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 {
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000072class CFGViewer : public Checker<check::ASTCodeBody> {
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000073public:
74 void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
75 BugReporter &BR) const {
76 if (CFG *cfg = mgr.getCFG(D)) {
David Blaikie4e4d0842012-03-11 07:00:24 +000077 cfg->viewCFG(mgr.getLangOpts());
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000078 }
79 }
80};
81}
82
83void ento::registerCFGViewer(CheckerManager &mgr) {
84 mgr.registerChecker<CFGViewer>();
85}
86
87//===----------------------------------------------------------------------===//
88// CFGDumper
89//===----------------------------------------------------------------------===//
90
91namespace {
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000092class CFGDumper : public Checker<check::ASTCodeBody> {
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000093public:
94 void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
95 BugReporter &BR) const {
96 if (CFG *cfg = mgr.getCFG(D)) {
David Blaikie4e4d0842012-03-11 07:00:24 +000097 cfg->dump(mgr.getLangOpts(),
Ted Kremenek682060c2011-12-22 23:33:52 +000098 llvm::sys::Process::StandardErrHasColors());
Argyrios Kyrtzidis2d67b902011-02-17 21:39:39 +000099 }
100 }
101};
102}
103
104void ento::registerCFGDumper(CheckerManager &mgr) {
105 mgr.registerChecker<CFGDumper>();
106}
Anna Zaks196b8cf2012-03-08 00:42:23 +0000107
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}
Ted Kremenek43e8ef02012-10-01 18:28:14 +0000147
148
149//===----------------------------------------------------------------------===//
150// ConfigDumper
151//===----------------------------------------------------------------------===//
152
153namespace {
154class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
155public:
156 void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
157 AnalysisManager& mgr,
158 BugReporter &BR) const {
159
160 const AnalyzerOptions::ConfigTable &Config = mgr.options.Config;
161 AnalyzerOptions::ConfigTable::const_iterator I =
162 Config.begin(), E = Config.end();
163
164 std::vector<StringRef> Keys;
165 for (; I != E ; ++I) { Keys.push_back(I->getKey()); }
166 sort(Keys.begin(), Keys.end());
167
168 llvm::errs() << "[config]\n";
169 for (unsigned i = 0, n = Keys.size(); i < n ; ++i) {
170 StringRef Key = Keys[i];
171 I = Config.find(Key);
172 llvm::errs() << Key << " = " << I->second << '\n';
173 }
174 llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
175 }
176};
177}
178
179void ento::registerConfigDumper(CheckerManager &mgr) {
180 mgr.registerChecker<ConfigDumper>();
181}