[cfe-commits] r89927 - in /cfe/trunk: include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/MemRegion.cpp

Ted Kremenek kremenek at apple.com
Wed Nov 25 18:34:36 PST 2009


Author: kremenek
Date: Wed Nov 25 20:34:36 2009
New Revision: 89927

URL: http://llvm.org/viewvc/llvm-project?rev=89927&view=rev
Log:
Add iterators to BlockDataRegion that allow clients to iterate over the VarRegions for "captured" variables for a block.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
    cfe/trunk/lib/Analysis/MemRegion.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=89927&r1=89926&r2=89927&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Wed Nov 25 20:34:36 2009
@@ -35,6 +35,7 @@
 class MemRegionManager;
 class MemSpaceRegion;
 class LocationContext;
+class VarRegion;
 
 //===----------------------------------------------------------------------===//
 // Base region classes.
@@ -42,6 +43,7 @@
 
 /// MemRegion - The root abstract class for all memory regions.
 class MemRegion : public llvm::FoldingSetNode {
+  friend class MemRegionManager;
 public:
   enum Kind { MemSpaceRegionKind,
               SymbolicRegionKind,
@@ -329,13 +331,18 @@
 class BlockDataRegion : public SubRegion {
   const BlockTextRegion *BC;
   const LocationContext *LC;
+  void *ReferencedVars;
 public:  
   BlockDataRegion(const BlockTextRegion *bc, 
                   const LocationContext *lc,
                   const MemRegion *sreg)
-  : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc) {}
+  : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
 
   const BlockTextRegion *getCodeRegion() const { return BC; }
+  
+  typedef const MemRegion * const * referenced_vars_iterator;
+  referenced_vars_iterator referenced_vars_begin() const;
+  referenced_vars_iterator referenced_vars_end() const;  
     
   virtual void dumpToStream(llvm::raw_ostream& os) const;
     
@@ -348,6 +355,8 @@
   static bool classof(const MemRegion* R) {
     return R->getKind() == BlockDataRegionKind;
   }
+private:
+  void LazyInitializeReferencedVars();
 };
 
 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
@@ -650,9 +659,11 @@
     : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
       unknown(0), code(0) {}
 
-  ~MemRegionManager() {}
+  ~MemRegionManager();
 
   ASTContext &getContext() { return C; }
+  
+  llvm::BumpPtrAllocator &getAllocator() { return A; }
 
   /// getStackRegion - Retrieve the memory region associated with the
   ///  current stack frame.

Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=89927&r1=89926&r2=89927&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Wed Nov 25 20:34:36 2009
@@ -17,15 +17,25 @@
 #include "clang/Analysis/PathSensitive/MemRegion.h"
 #include "clang/Analysis/PathSensitive/ValueManager.h"
 #include "clang/Analysis/PathSensitive/AnalysisContext.h"
+#include "clang/AST/StmtVisitor.h"
 
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-// Basic methods.
+// Object destruction.
 //===----------------------------------------------------------------------===//
 
 MemRegion::~MemRegion() {}
 
+MemRegionManager::~MemRegionManager() {
+  // All regions and their data are BumpPtrAllocated.  No need to call
+  // their destructors.
+}
+
+//===----------------------------------------------------------------------===//
+// Basic methods.
+//===----------------------------------------------------------------------===//
+
 bool SubRegion::isSubRegionOf(const MemRegion* R) const {
   const MemRegion* r = getSuperRegion();
   while (r != 0) {
@@ -525,3 +535,53 @@
   return RegionRawOffset(superR, offset);
 }
 
+//===----------------------------------------------------------------------===//
+// BlockDataRegion
+//===----------------------------------------------------------------------===//
+
+void BlockDataRegion::LazyInitializeReferencedVars() {
+  if (ReferencedVars)
+    return;
+
+  AnalysisContext *AC = LC->getAnalysisContext();
+  AnalysisContext::referenced_decls_iterator I, E;
+  llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
+  
+  if (I == E) {
+    ReferencedVars = (void*) 0x1;
+    return;
+  }
+    
+  MemRegionManager &MemMgr = *getMemRegionManager();
+  llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
+  BumpVectorContext BC(A);
+  
+  typedef BumpVector<const MemRegion*> VarVec;
+  VarVec *BV = (VarVec*) A.Allocate<VarVec>();
+  new (BV) VarVec(BC, (E - I) / sizeof(*I));
+  
+  for ( ; I != E; ++I)
+    BV->push_back(MemMgr.getVarRegion(*I, LC), BC);
+  
+  ReferencedVars = BV;
+}
+
+BlockDataRegion::referenced_vars_iterator
+BlockDataRegion::referenced_vars_begin() const {
+  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
+
+  BumpVector<const MemRegion*> *Vec =
+    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
+  
+  return Vec == (void*) 0x1 ? NULL : Vec->begin();  
+}
+
+BlockDataRegion::referenced_vars_iterator
+BlockDataRegion::referenced_vars_end() const {
+  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
+
+  BumpVector<const MemRegion*> *Vec =
+    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
+  
+  return Vec == (void*) 0x1 ? NULL : Vec->end();  
+}





More information about the cfe-commits mailing list