Home | History | Annotate | Download | only in Checkers
      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/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 }
    182