diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-07-19 14:18:43 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-07-19 14:18:43 +0000 |
commit | 74fb1a493cf5d2dd0fb51a4eadf74e85e10a3457 (patch) | |
tree | f690eaccfe32995ffd469550dd3147da723d3c4d | |
parent | 22de49cbed981aec160556761113b667598c2a63 (diff) |
Add hooks into the CFG builder to force that specific expressions are always CFGElements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135479 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/AnalysisContext.h | 9 | ||||
-rw-r--r-- | include/clang/Analysis/CFG.h | 20 | ||||
-rw-r--r-- | lib/Analysis/CFG.cpp | 12 |
3 files changed, 32 insertions, 9 deletions
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 6a1876e659..421dbb0dff 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -81,6 +81,15 @@ public: idx::TranslationUnit *getTranslationUnit() const { return TU; } + /// Return the build options used to construct the CFG. + CFG::BuildOptions &getCFGBuildOptions() { + return cfgBuildOptions; + } + + const CFG::BuildOptions &getCFGBuildOptions() const { + return cfgBuildOptions; + } + /// getAddEHEdges - Return true iff we are adding exceptional edges from /// callExprs. If this is false, then try/catch statements and blocks /// reachable from them can appear to be dead in the CFG, analysis passes must diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index ca46459afd..83f5b1549e 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -21,6 +21,8 @@ #include "llvm/Support/Casting.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/BitVector.h" +#include "clang/AST/Stmt.h" #include "clang/Analysis/Support/BumpVector.h" #include "clang/Basic/SourceLocation.h" #include <cassert> @@ -533,6 +535,7 @@ public: //===--------------------------------------------------------------------===// class BuildOptions { + llvm::BitVector alwaysAddMask; public: typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs; ForcedBlkExprs **forcedBlkExprs; @@ -541,12 +544,21 @@ public: bool AddEHEdges:1; bool AddInitializers:1; bool AddImplicitDtors:1; + + bool alwaysAdd(const Stmt *stmt) const { + return alwaysAddMask[stmt->getStmtClass()]; + } + + void setAlwaysAdd(Stmt::StmtClass stmtClass) { + alwaysAddMask[stmtClass] = true; + } BuildOptions() - : forcedBlkExprs(0), PruneTriviallyFalseEdges(true) - , AddEHEdges(false) - , AddInitializers(false) - , AddImplicitDtors(false) {} + : alwaysAddMask(Stmt::lastStmtConstant, false) + ,forcedBlkExprs(0), PruneTriviallyFalseEdges(true) + ,AddEHEdges(false) + ,AddInitializers(false) + ,AddImplicitDtors(false) {} }; /// buildCFG - Builds a CFG from an AST. The responsibility to free the diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index f231c147f1..2a13450b4d 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -394,7 +394,7 @@ private: // Interface to CFGBlock - adding CFGElements. void appendStmt(CFGBlock *B, const Stmt *S) { - if (alwaysAdd(S)) + if (alwaysAdd(S) && cachedEntry) cachedEntry->second = B; // All block-level expressions should have already been IgnoreParens()ed. @@ -461,15 +461,17 @@ inline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder, } bool CFGBuilder::alwaysAdd(const Stmt *stmt) { + bool shouldAdd = BuildOpts.alwaysAdd(stmt); + if (!BuildOpts.forcedBlkExprs) - return false; + return shouldAdd; if (lastLookup == stmt) { if (cachedEntry) { assert(cachedEntry->first == stmt); return true; } - return false; + return shouldAdd; } lastLookup = stmt; @@ -480,13 +482,13 @@ bool CFGBuilder::alwaysAdd(const Stmt *stmt) { if (!fb) { // No need to update 'cachedEntry', since it will always be null. assert(cachedEntry == 0); - return false; + return shouldAdd; } CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt); if (itr == fb->end()) { cachedEntry = 0; - return false; + return shouldAdd; } cachedEntry = &*itr; |