]> granicus.if.org Git - clang/commitdiff
Add hooks into the CFG builder to force that specific expressions are always CFGElements.
authorTed Kremenek <kremenek@apple.com>
Tue, 19 Jul 2011 14:18:43 +0000 (14:18 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 19 Jul 2011 14:18:43 +0000 (14:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135479 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/AnalysisContext.h
include/clang/Analysis/CFG.h
lib/Analysis/CFG.cpp

index 6a1876e6590089429c3cb1c2c680ad455264abef..421dbb0dff7e8b4ef1098312b3e4eb0dd31260fe 100644 (file)
@@ -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
index ca46459afd9a878300e80847fefc898dbac40580..83f5b1549eb4d98f0da251e6bc88639bbf122a1d 100644 (file)
@@ -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
index f231c147f11ee4f1f834f411ce77321626d8eb5b..2a13450b4dc37fa679301827c2cad455e91cabc5 100644 (file)
@@ -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;