]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Checkers / DebugCheckers.cpp
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 checkers that display debugging information.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ClangSACheckers.h"
15 #include "clang/Analysis/Analyses/Dominators.h"
16 #include "clang/Analysis/Analyses/LiveVariables.h"
17 #include "clang/Analysis/CallGraph.h"
18 #include "clang/StaticAnalyzer/Core/Checker.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
20 #include "llvm/Support/Process.h"
21
22 using namespace clang;
23 using namespace ento;
24
25 //===----------------------------------------------------------------------===//
26 // DominatorsTreeDumper
27 //===----------------------------------------------------------------------===//
28
29 namespace {
30 class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
31 public:
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
43 void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
44   mgr.registerChecker<DominatorsTreeDumper>();
45 }
46
47 //===----------------------------------------------------------------------===//
48 // LiveVariablesDumper
49 //===----------------------------------------------------------------------===//
50
51 namespace {
52 class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
53 public:
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
63 void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
64   mgr.registerChecker<LiveVariablesDumper>();
65 }
66
67 //===----------------------------------------------------------------------===//
68 // CFGViewer
69 //===----------------------------------------------------------------------===//
70
71 namespace {
72 class CFGViewer : public Checker<check::ASTCodeBody> {
73 public:
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
83 void ento::registerCFGViewer(CheckerManager &mgr) {
84   mgr.registerChecker<CFGViewer>();
85 }
86
87 //===----------------------------------------------------------------------===//
88 // CFGDumper
89 //===----------------------------------------------------------------------===//
90
91 namespace {
92 class CFGDumper : public Checker<check::ASTCodeBody> {
93 public:
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
104 void ento::registerCFGDumper(CheckerManager &mgr) {
105   mgr.registerChecker<CFGDumper>();
106 }
107
108 //===----------------------------------------------------------------------===//
109 // CallGraphViewer
110 //===----------------------------------------------------------------------===//
111
112 namespace {
113 class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
114 public:
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
124 void ento::registerCallGraphViewer(CheckerManager &mgr) {
125   mgr.registerChecker<CallGraphViewer>();
126 }
127
128 //===----------------------------------------------------------------------===//
129 // CallGraphDumper
130 //===----------------------------------------------------------------------===//
131
132 namespace {
133 class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
134 public:
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
144 void ento::registerCallGraphDumper(CheckerManager &mgr) {
145   mgr.registerChecker<CallGraphDumper>();
146 }
147
148
149 //===----------------------------------------------------------------------===//
150 // ConfigDumper
151 //===----------------------------------------------------------------------===//
152
153 namespace {
154 class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
155 public:
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
179 void ento::registerConfigDumper(CheckerManager &mgr) {
180   mgr.registerChecker<ConfigDumper>();
181 }