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