diff options
author | Anna Zaks <ganna@apple.com> | 2012-04-03 02:05:47 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-04-03 02:05:47 +0000 |
commit | e62f048960645b79363408fdead53fec2a063c52 (patch) | |
tree | 9010101e69af556f2371b82cf4c346f39a23dfdc /include/clang | |
parent | 0ea6164a7ff685f64ddfe3ec983a2b052ea91afb (diff) |
[analyzer] Record the basic blocks covered by the analyzes run.
Store this info inside the function summary generated for all analyzed
functions. This is useful for coverage stats and can be helpful for
analyzer state space search strategies.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153923 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
4 files changed, 105 insertions, 33 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index f8f7e25d8b..3cbecf7d6e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -30,33 +30,6 @@ namespace idx { namespace ento { class CheckerManager; -typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls; - -class FunctionSummariesTy { - struct FunctionSummary { - /// True if this function has reached a max block count while inlined from - /// at least one call site. - bool MayReachMaxBlockCount; - FunctionSummary() : MayReachMaxBlockCount(false) {} - }; - - typedef llvm::DenseMap<const Decl*, FunctionSummary> MapTy; - MapTy Map; - -public: - void markReachedMaxBlockCount(const Decl* D) { - Map[D].MayReachMaxBlockCount = true; - } - - bool hasReachedMaxBlockCount(const Decl* D) { - MapTy::const_iterator I = Map.find(D); - if (I != Map.end()) - return I->second.MayReachMaxBlockCount; - return false; - } - -}; - class AnalysisManager : public BugReporterData { virtual void anchor(); AnalysisDeclContextManager AnaCtxMgr; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 85d92ff5f7..d9156441db 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -18,6 +18,7 @@ #include "clang/AST/Expr.h" #include "clang/Analysis/AnalysisContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h" #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h" #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" #include "llvm/ADT/OwningPtr.h" @@ -83,6 +84,10 @@ private: /// AnalysisConsumer. It can be null. SetOfDecls *AnalyzedCallees; + /// The information about functions shared by the whole translation unit. + /// (This data is owned by AnalysisConsumer.) + FunctionSummariesTy *FunctionSummaries; + void generateNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred); @@ -104,11 +109,13 @@ private: public: /// Construct a CoreEngine object to analyze the provided CFG using /// a DFS exploration of the exploded graph. - CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees) + CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees, + FunctionSummariesTy *FS) : SubEng(subengine), G(new ExplodedGraph()), WList(WorkList::makeBFS()), BCounterFactory(G->getAllocator()), - AnalyzedCallees(VisitedCallees) {} + AnalyzedCallees(VisitedCallees), + FunctionSummaries(FS){} ~CoreEngine() { delete WList; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index f4d2e6027b..4d1ee5436f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -90,10 +90,6 @@ class ExprEngine : public SubEngine { /// destructor is called before the rest of the ExprEngine is destroyed. GRBugReporter BR; - /// The information about functions shared by the whole translation unit. - /// (This data is owned by AnalysisConsumer.) - FunctionSummariesTy *FunctionSummaries; - public: ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees, FunctionSummariesTy *FS); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h new file mode 100644 index 0000000000..e1e15620fa --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h @@ -0,0 +1,96 @@ +//== FunctionSummary.h - Stores summaries of functions. ------------*- 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 a summary of a function gathered/used by static analyzes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H +#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H + +#include "clang/AST/Decl.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/BitVector.h" + +namespace clang { +namespace ento { +typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls; + +class FunctionSummariesTy { + struct FunctionSummary { + /// True if this function has reached a max block count while inlined from + /// at least one call site. + bool MayReachMaxBlockCount; + + /// Total number of blocks in the function. + unsigned TotalBasicBlocks; + + /// Marks the IDs of the basic blocks visited during the analyzes. + llvm::BitVector VisitedBasicBlocks; + + FunctionSummary() : + MayReachMaxBlockCount(false), + TotalBasicBlocks(0), + VisitedBasicBlocks(0) {} + }; + + typedef llvm::DenseMap<const Decl*, FunctionSummary*> MapTy; + MapTy Map; + +public: + ~FunctionSummariesTy(); + + MapTy::iterator findOrInsertSummary(const Decl *D) { + MapTy::iterator I = Map.find(D); + if (I != Map.end()) + return I; + FunctionSummary *DS = new FunctionSummary(); + I = Map.insert(std::pair<const Decl*, FunctionSummary*>(D, DS)).first; + assert(I != Map.end()); + return I; + } + + void markReachedMaxBlockCount(const Decl* D) { + MapTy::iterator I = findOrInsertSummary(D); + I->second->MayReachMaxBlockCount = true; + } + + bool hasReachedMaxBlockCount(const Decl* D) { + MapTy::const_iterator I = Map.find(D); + if (I != Map.end()) + return I->second->MayReachMaxBlockCount; + return false; + } + + void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { + MapTy::iterator I = findOrInsertSummary(D); + llvm::BitVector &Blocks = I->second->VisitedBasicBlocks; + assert(ID < TotalIDs); + if (TotalIDs > Blocks.size()) { + Blocks.resize(TotalIDs); + I->second->TotalBasicBlocks = TotalIDs; + } + Blocks[ID] = true; + } + + unsigned getNumVisitedBasicBlocks(const Decl* D) { + MapTy::const_iterator I = Map.find(D); + if (I != Map.end()) + return I->second->VisitedBasicBlocks.count(); + return 0; + } + + unsigned getTotalNumBasicBlocks(); + unsigned getTotalNumVisitedBasicBlocks(); +}; + +}} // end clang ento namespaces + +#endif |