DebugCheckers.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. #include "ClangSACheckers.h"
  14. #include "clang/Analysis/Analyses/Dominators.h"
  15. #include "clang/Analysis/Analyses/LiveVariables.h"
  16. #include "clang/Analysis/CallGraph.h"
  17. #include "clang/StaticAnalyzer/Core/Checker.h"
  18. #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
  19. #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
  20. #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
  21. #include "llvm/Support/Process.h"
  22. using namespace clang;
  23. using namespace ento;
  24. //===----------------------------------------------------------------------===//
  25. // DominatorsTreeDumper
  26. //===----------------------------------------------------------------------===//
  27. namespace {
  28. class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
  29. public:
  30. void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
  31. BugReporter &BR) const {
  32. if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
  33. DominatorTree dom;
  34. dom.buildDominatorTree(*AC);
  35. dom.dump();
  36. }
  37. }
  38. };
  39. }
  40. void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
  41. mgr.registerChecker<DominatorsTreeDumper>();
  42. }
  43. //===----------------------------------------------------------------------===//
  44. // LiveVariablesDumper
  45. //===----------------------------------------------------------------------===//
  46. namespace {
  47. class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
  48. public:
  49. void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
  50. BugReporter &BR) const {
  51. if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
  52. L->dumpBlockLiveness(mgr.getSourceManager());
  53. }
  54. }
  55. };
  56. }
  57. void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
  58. mgr.registerChecker<LiveVariablesDumper>();
  59. }
  60. //===----------------------------------------------------------------------===//
  61. // CFGViewer
  62. //===----------------------------------------------------------------------===//
  63. namespace {
  64. class CFGViewer : public Checker<check::ASTCodeBody> {
  65. public:
  66. void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
  67. BugReporter &BR) const {
  68. if (CFG *cfg = mgr.getCFG(D)) {
  69. cfg->viewCFG(mgr.getLangOpts());
  70. }
  71. }
  72. };
  73. }
  74. void ento::registerCFGViewer(CheckerManager &mgr) {
  75. mgr.registerChecker<CFGViewer>();
  76. }
  77. //===----------------------------------------------------------------------===//
  78. // CFGDumper
  79. //===----------------------------------------------------------------------===//
  80. namespace {
  81. class CFGDumper : public Checker<check::ASTCodeBody> {
  82. public:
  83. void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
  84. BugReporter &BR) const {
  85. PrintingPolicy Policy(mgr.getLangOpts());
  86. Policy.TerseOutput = true;
  87. Policy.PolishForDeclaration = true;
  88. D->print(llvm::errs(), Policy);
  89. if (CFG *cfg = mgr.getCFG(D)) {
  90. cfg->dump(mgr.getLangOpts(),
  91. llvm::sys::Process::StandardErrHasColors());
  92. }
  93. }
  94. };
  95. }
  96. void ento::registerCFGDumper(CheckerManager &mgr) {
  97. mgr.registerChecker<CFGDumper>();
  98. }
  99. //===----------------------------------------------------------------------===//
  100. // CallGraphViewer
  101. //===----------------------------------------------------------------------===//
  102. namespace {
  103. class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
  104. public:
  105. void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
  106. BugReporter &BR) const {
  107. CallGraph CG;
  108. CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
  109. CG.viewGraph();
  110. }
  111. };
  112. }
  113. void ento::registerCallGraphViewer(CheckerManager &mgr) {
  114. mgr.registerChecker<CallGraphViewer>();
  115. }
  116. //===----------------------------------------------------------------------===//
  117. // CallGraphDumper
  118. //===----------------------------------------------------------------------===//
  119. namespace {
  120. class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
  121. public:
  122. void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
  123. BugReporter &BR) const {
  124. CallGraph CG;
  125. CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
  126. CG.dump();
  127. }
  128. };
  129. }
  130. void ento::registerCallGraphDumper(CheckerManager &mgr) {
  131. mgr.registerChecker<CallGraphDumper>();
  132. }
  133. //===----------------------------------------------------------------------===//
  134. // ConfigDumper
  135. //===----------------------------------------------------------------------===//
  136. namespace {
  137. class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
  138. typedef AnalyzerOptions::ConfigTable Table;
  139. // HLSL Change: changed calling convention to __cdecl
  140. static int __cdecl compareEntry(const Table::MapEntryTy *const *LHS,
  141. const Table::MapEntryTy *const *RHS) {
  142. return (*LHS)->getKey().compare((*RHS)->getKey());
  143. }
  144. public:
  145. void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
  146. AnalysisManager& mgr,
  147. BugReporter &BR) const {
  148. const Table &Config = mgr.options.Config;
  149. SmallVector<const Table::MapEntryTy *, 32> Keys;
  150. for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
  151. ++I)
  152. Keys.push_back(&*I);
  153. llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
  154. llvm::errs() << "[config]\n";
  155. for (unsigned I = 0, E = Keys.size(); I != E; ++I)
  156. llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n';
  157. llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
  158. }
  159. };
  160. }
  161. void ento::registerConfigDumper(CheckerManager &mgr) {
  162. mgr.registerChecker<ConfigDumper>();
  163. }
  164. //===----------------------------------------------------------------------===//
  165. // ExplodedGraph Viewer
  166. //===----------------------------------------------------------------------===//
  167. namespace {
  168. class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
  169. public:
  170. ExplodedGraphViewer() {}
  171. void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
  172. Eng.ViewGraph(0);
  173. }
  174. };
  175. }
  176. void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
  177. mgr.registerChecker<ExplodedGraphViewer>();
  178. }