1 //==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a checkers that display debugging information.
12 //===----------------------------------------------------------------------===//
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"
22 using namespace clang;
25 //===----------------------------------------------------------------------===//
26 // DominatorsTreeDumper
27 //===----------------------------------------------------------------------===//
30 class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
32 void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
33 BugReporter &BR) const {
34 if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
36 dom.buildDominatorTree(*AC);
43 void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
44 mgr.registerChecker<DominatorsTreeDumper>();
47 //===----------------------------------------------------------------------===//
48 // LiveVariablesDumper
49 //===----------------------------------------------------------------------===//
52 class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
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());
63 void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
64 mgr.registerChecker<LiveVariablesDumper>();
67 //===----------------------------------------------------------------------===//
69 //===----------------------------------------------------------------------===//
72 class CFGViewer : public Checker<check::ASTCodeBody> {
74 void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
75 BugReporter &BR) const {
76 if (CFG *cfg = mgr.getCFG(D)) {
77 cfg->viewCFG(mgr.getLangOpts());
83 void ento::registerCFGViewer(CheckerManager &mgr) {
84 mgr.registerChecker<CFGViewer>();
87 //===----------------------------------------------------------------------===//
89 //===----------------------------------------------------------------------===//
92 class CFGDumper : public Checker<check::ASTCodeBody> {
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());
104 void ento::registerCFGDumper(CheckerManager &mgr) {
105 mgr.registerChecker<CFGDumper>();
108 //===----------------------------------------------------------------------===//
110 //===----------------------------------------------------------------------===//
113 class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
115 void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
116 BugReporter &BR) const {
118 CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
124 void ento::registerCallGraphViewer(CheckerManager &mgr) {
125 mgr.registerChecker<CallGraphViewer>();
128 //===----------------------------------------------------------------------===//
130 //===----------------------------------------------------------------------===//
133 class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
135 void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
136 BugReporter &BR) const {
138 CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
144 void ento::registerCallGraphDumper(CheckerManager &mgr) {
145 mgr.registerChecker<CallGraphDumper>();
149 //===----------------------------------------------------------------------===//
151 //===----------------------------------------------------------------------===//
154 class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
156 void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
157 AnalysisManager& mgr,
158 BugReporter &BR) const {
160 const AnalyzerOptions::ConfigTable &Config = mgr.options.Config;
161 AnalyzerOptions::ConfigTable::const_iterator I =
162 Config.begin(), E = Config.end();
164 std::vector<StringRef> Keys;
165 for (; I != E ; ++I) { Keys.push_back(I->getKey()); }
166 sort(Keys.begin(), Keys.end());
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';
174 llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
179 void ento::registerConfigDumper(CheckerManager &mgr) {
180 mgr.registerChecker<ConfigDumper>();