DebugCheckers.cpp revision 6026df1e5d518a958aef342d55a9e5d0fbdb85ca
12d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==// 22d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 32d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 42d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 52d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 62d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 72d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 82d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 92d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 106026df1e5d518a958aef342d55a9e5d0fbdb85caJordan Rose// This file defines checkers that display debugging information. 112d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// 122d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 132d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 142d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis#include "ClangSACheckers.h" 1558f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek#include "clang/Analysis/Analyses/Dominators.h" 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/Analyses/LiveVariables.h" 17196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks#include "clang/Analysis/CallGraph.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/Checker.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 20682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek#include "llvm/Support/Process.h" 212d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 222d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisusing namespace clang; 232d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisusing namespace ento; 242d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 252d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 2658f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek// DominatorsTreeDumper 2758f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek//===----------------------------------------------------------------------===// 2858f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek 2958f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremeneknamespace { 3058f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenekclass DominatorsTreeDumper : public Checker<check::ASTCodeBody> { 3158f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenekpublic: 3258f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 3358f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek BugReporter &BR) const { 3458f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { 3502f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks DominatorTree dom; 3602f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks dom.buildDominatorTree(*AC); 3758f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek dom.dump(); 3858f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek } 3958f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek } 4058f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek}; 4158f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek} 4258f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek 4358f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenekvoid ento::registerDominatorsTreeDumper(CheckerManager &mgr) { 4458f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek mgr.registerChecker<DominatorsTreeDumper>(); 4558f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek} 4658f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek 4758f6f1e37ab32fdd0c8bab6771d8e09bc139e9edTed Kremenek//===----------------------------------------------------------------------===// 482d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// LiveVariablesDumper 492d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 502d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 512d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisnamespace { 52ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass LiveVariablesDumper : public Checker<check::ASTCodeBody> { 532d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidispublic: 542d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 552d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis BugReporter &BR) const { 56a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) { 572d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis L->dumpBlockLiveness(mgr.getSourceManager()); 582d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 592d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 602d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}; 612d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 622d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 632d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerLiveVariablesDumper(CheckerManager &mgr) { 642d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis mgr.registerChecker<LiveVariablesDumper>(); 652d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 662d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 672d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 682d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// CFGViewer 692d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 702d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 712d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisnamespace { 72ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass CFGViewer : public Checker<check::ASTCodeBody> { 732d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidispublic: 742d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 752d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis BugReporter &BR) const { 762d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis if (CFG *cfg = mgr.getCFG(D)) { 774e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie cfg->viewCFG(mgr.getLangOpts()); 782d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 792d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 802d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}; 812d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 822d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 832d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerCFGViewer(CheckerManager &mgr) { 842d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis mgr.registerChecker<CFGViewer>(); 852d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 862d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 872d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 882d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis// CFGDumper 892d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 902d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 912d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisnamespace { 92ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass CFGDumper : public Checker<check::ASTCodeBody> { 932d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidispublic: 942d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, 952d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis BugReporter &BR) const { 962d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis if (CFG *cfg = mgr.getCFG(D)) { 974e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie cfg->dump(mgr.getLangOpts(), 98682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek llvm::sys::Process::StandardErrHasColors()); 992d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 1002d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis } 1012d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis}; 1022d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 1032d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis 1042d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidisvoid ento::registerCFGDumper(CheckerManager &mgr) { 1052d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis mgr.registerChecker<CFGDumper>(); 1062d67b90a21c9c1093e6598809c2cbc832919cfe6Argyrios Kyrtzidis} 107196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 108196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 109196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// CallGraphViewer 110196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 111196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 112196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace { 113196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > { 114196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic: 115196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 116196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks BugReporter &BR) const { 117196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CallGraph CG; 118196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 119196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.viewGraph(); 120196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks } 121196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}; 122196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 123196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 124196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid ento::registerCallGraphViewer(CheckerManager &mgr) { 125196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks mgr.registerChecker<CallGraphViewer>(); 126196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 127196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 128196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 129196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks// CallGraphDumper 130196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks//===----------------------------------------------------------------------===// 131196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 132196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksnamespace { 133196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksclass CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > { 134196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zakspublic: 135196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, 136196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks BugReporter &BR) const { 137196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CallGraph CG; 138196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU)); 139196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks CG.dump(); 140196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks } 141196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks}; 142196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 143196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks 144196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaksvoid ento::registerCallGraphDumper(CheckerManager &mgr) { 145196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks mgr.registerChecker<CallGraphDumper>(); 146196b8cfe9cfcc452eb2f83aa4ad330c2324f8c7dAnna Zaks} 14743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 14843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 14943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek//===----------------------------------------------------------------------===// 15043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek// ConfigDumper 15143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek//===----------------------------------------------------------------------===// 15243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 15343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremeneknamespace { 15443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekclass ConfigDumper : public Checker< check::EndOfTranslationUnit > { 15543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekpublic: 15643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, 15743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek AnalysisManager& mgr, 15843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek BugReporter &BR) const { 15943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 16043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek const AnalyzerOptions::ConfigTable &Config = mgr.options.Config; 16143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek AnalyzerOptions::ConfigTable::const_iterator I = 16243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek Config.begin(), E = Config.end(); 16343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 16443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek std::vector<StringRef> Keys; 16543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek for (; I != E ; ++I) { Keys.push_back(I->getKey()); } 16643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek sort(Keys.begin(), Keys.end()); 16743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 16843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek llvm::errs() << "[config]\n"; 16943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek for (unsigned i = 0, n = Keys.size(); i < n ; ++i) { 17043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek StringRef Key = Keys[i]; 17143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek I = Config.find(Key); 17243e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek llvm::errs() << Key << " = " << I->second << '\n'; 17343e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek } 17443e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n'; 17543e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek } 17643e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek}; 17743e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek} 17843e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek 17943e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenekvoid ento::registerConfigDumper(CheckerManager &mgr) { 18043e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek mgr.registerChecker<ConfigDumper>(); 18143e8ef0b90dffcf9bda4fc2d3e6b21feb1e15bfbTed Kremenek} 182