123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- //==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines checkers that display debugging information.
- //
- //===----------------------------------------------------------------------===//
- #include "ClangSACheckers.h"
- #include "clang/Analysis/Analyses/Dominators.h"
- #include "clang/Analysis/Analyses/LiveVariables.h"
- #include "clang/Analysis/CallGraph.h"
- #include "clang/StaticAnalyzer/Core/Checker.h"
- #include "clang/StaticAnalyzer/Core/IssueHash.h"
- #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
- #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
- #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
- #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
- #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
- #include "llvm/Support/Process.h"
- using namespace clang;
- using namespace ento;
- //===----------------------------------------------------------------------===//
- // DominatorsTreeDumper
- //===----------------------------------------------------------------------===//
- namespace {
- class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
- public:
- void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) const {
- if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
- DominatorTree dom;
- dom.buildDominatorTree(*AC);
- dom.dump();
- }
- }
- };
- }
- void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
- mgr.registerChecker<DominatorsTreeDumper>();
- }
- //===----------------------------------------------------------------------===//
- // LiveVariablesDumper
- //===----------------------------------------------------------------------===//
- namespace {
- class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
- public:
- void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) const {
- if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
- L->dumpBlockLiveness(mgr.getSourceManager());
- }
- }
- };
- }
- void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
- mgr.registerChecker<LiveVariablesDumper>();
- }
- //===----------------------------------------------------------------------===//
- // CFGViewer
- //===----------------------------------------------------------------------===//
- namespace {
- class CFGViewer : public Checker<check::ASTCodeBody> {
- public:
- void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) const {
- if (CFG *cfg = mgr.getCFG(D)) {
- cfg->viewCFG(mgr.getLangOpts());
- }
- }
- };
- }
- void ento::registerCFGViewer(CheckerManager &mgr) {
- mgr.registerChecker<CFGViewer>();
- }
- //===----------------------------------------------------------------------===//
- // CFGDumper
- //===----------------------------------------------------------------------===//
- namespace {
- class CFGDumper : public Checker<check::ASTCodeBody> {
- public:
- void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
- BugReporter &BR) const {
- PrintingPolicy Policy(mgr.getLangOpts());
- Policy.TerseOutput = true;
- Policy.PolishForDeclaration = true;
- D->print(llvm::errs(), Policy);
- if (CFG *cfg = mgr.getCFG(D)) {
- cfg->dump(mgr.getLangOpts(),
- llvm::sys::Process::StandardErrHasColors());
- }
- }
- };
- }
- void ento::registerCFGDumper(CheckerManager &mgr) {
- mgr.registerChecker<CFGDumper>();
- }
- //===----------------------------------------------------------------------===//
- // CallGraphViewer
- //===----------------------------------------------------------------------===//
- namespace {
- class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
- public:
- void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
- BugReporter &BR) const {
- CallGraph CG;
- CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
- CG.viewGraph();
- }
- };
- }
- void ento::registerCallGraphViewer(CheckerManager &mgr) {
- mgr.registerChecker<CallGraphViewer>();
- }
- //===----------------------------------------------------------------------===//
- // CallGraphDumper
- //===----------------------------------------------------------------------===//
- namespace {
- class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
- public:
- void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
- BugReporter &BR) const {
- CallGraph CG;
- CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
- CG.dump();
- }
- };
- }
- void ento::registerCallGraphDumper(CheckerManager &mgr) {
- mgr.registerChecker<CallGraphDumper>();
- }
- //===----------------------------------------------------------------------===//
- // ConfigDumper
- //===----------------------------------------------------------------------===//
- namespace {
- class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
- typedef AnalyzerOptions::ConfigTable Table;
- static int compareEntry(const Table::MapEntryTy *const *LHS,
- const Table::MapEntryTy *const *RHS) {
- return (*LHS)->getKey().compare((*RHS)->getKey());
- }
- public:
- void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
- AnalysisManager& mgr,
- BugReporter &BR) const {
- const Table &Config = mgr.options.Config;
- SmallVector<const Table::MapEntryTy *, 32> Keys;
- for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
- ++I)
- Keys.push_back(&*I);
- llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
- llvm::errs() << "[config]\n";
- for (unsigned I = 0, E = Keys.size(); I != E; ++I)
- llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n';
- llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
- }
- };
- }
- void ento::registerConfigDumper(CheckerManager &mgr) {
- mgr.registerChecker<ConfigDumper>();
- }
- //===----------------------------------------------------------------------===//
- // ExplodedGraph Viewer
- //===----------------------------------------------------------------------===//
- namespace {
- class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
- public:
- ExplodedGraphViewer() {}
- void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
- Eng.ViewGraph(0);
- }
- };
- }
- void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
- mgr.registerChecker<ExplodedGraphViewer>();
- }
- //===----------------------------------------------------------------------===//
- // DumpBugHash
- //===----------------------------------------------------------------------===//
- namespace {
- class BugHashDumper : public Checker<check::PostStmt<Stmt>> {
- public:
- mutable std::unique_ptr<BugType> BT;
- void checkPostStmt(const Stmt *S, CheckerContext &C) const {
- if (!BT)
- BT.reset(new BugType(this, "Dump hash components", "debug"));
- ExplodedNode *N = C.generateNonFatalErrorNode();
- if (!N)
- return;
- const LangOptions &Opts = C.getLangOpts();
- const SourceManager &SM = C.getSourceManager();
- FullSourceLoc FL(S->getLocStart(), SM);
- std::string HashContent =
- GetIssueString(SM, FL, getCheckName().getName(), BT->getCategory(),
- C.getLocationContext()->getDecl(), Opts);
- C.emitReport(llvm::make_unique<BugReport>(*BT, HashContent, N));
- }
- };
- }
- void ento::registerBugHashDumper(CheckerManager &mgr) {
- mgr.registerChecker<BugHashDumper>();
- }
|