]> granicus.if.org Git - clang/commitdiff
Add iterators to BlockDataRegion that allow clients to iterate over the VarRegions...
authorTed Kremenek <kremenek@apple.com>
Thu, 26 Nov 2009 02:34:36 +0000 (02:34 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 26 Nov 2009 02:34:36 +0000 (02:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89927 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/MemRegion.h
lib/Analysis/MemRegion.cpp

index 9a361501ceae1c24d4b2ca3f1acaafcb7256cf70..ed964978a44a95cd84292f8b1d7e0c19ca9b3aed 100644 (file)
@@ -35,6 +35,7 @@ namespace clang {
 class MemRegionManager;
 class MemSpaceRegion;
 class LocationContext;
+class VarRegion;
 
 //===----------------------------------------------------------------------===//
 // Base region classes.
@@ -42,6 +43,7 @@ class LocationContext;
 
 /// 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 @@ public:
 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 @@ public:
   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 @@ public:
     : 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.
index 430ec238c8db21d00ce97eed50ae7c7f8861094e..af8bd16ee681822b1a0b16354ecda414cc5bc199 100644 (file)
 #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 @@ RegionRawOffset ElementRegion::getAsRawOffset() const {
   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();  
+}