]> granicus.if.org Git - clang/commitdiff
Refactor some of the logic in MemRegionManager for constructing regions using
authorTed Kremenek <kremenek@apple.com>
Mon, 22 Jun 2009 23:13:13 +0000 (23:13 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 22 Jun 2009 23:13:13 +0000 (23:13 +0000)
member template functions and traits. The idea is to allow MemRegionManager to
construct subclasses of MemRegion that aren't declared in MemRegion.h (e.g.,
checker-specific regions).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73917 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 8afcc4c2414fe2cf9d957d845f04494bd31e739e..76d6a7a322e0d9e92266c9c0739daf83f6b1a348 100644 (file)
@@ -262,7 +262,9 @@ public:
 
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym);
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            SymbolRef sym,
+                            const MemRegion* superRegion);
   
   void print(llvm::raw_ostream& os) const;
   
@@ -277,7 +279,7 @@ class StringRegion : public TypedRegion {
   const StringLiteral* Str;
 protected:
 
-  StringRegion(const StringLiteral* str, MemRegion* sreg)
+  StringRegion(const StringLiteral* str, const MemRegion* sreg)
     : TypedRegion(sreg, StringRegionKind), Str(str) {}
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -399,7 +401,7 @@ class VarRegion : public DeclRegion {
   VarRegion(const VarDecl* vd, const MemRegion* sReg)
     : DeclRegion(vd, sReg, VarRegionKind) {}
 
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, VarDecl* VD,
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
                       const MemRegion* superRegion) {
     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
   }
@@ -600,6 +602,8 @@ public:
   /// onHeap - check if the region is allocated on the heap, usually by malloc.
   bool onHeap(const MemRegion* R);
   
+  bool hasStackStorage(const MemRegion* R);
+  
   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
   AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt);
   
@@ -646,14 +650,87 @@ public:
 
   CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t);
   CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t);
-
-  bool hasStackStorage(const MemRegion* R);
+  
+  template <typename RegionTy, typename A1>
+  RegionTy* getRegion(const A1 a1);
 
 private:
   MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
 };
+  
+//===----------------------------------------------------------------------===//
+// Out-of-line member template definitions.
+//===----------------------------------------------------------------------===//
+
+template<typename RegionTy> struct MemRegionManagerTrait;
+  
+template <typename RegionTy, typename A1>
+RegionTy* MemRegionManager::getRegion(const A1 a1) {
+
+  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
+    MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
+  
+  llvm::FoldingSetNodeID ID;  
+  RegionTy::ProfileRegion(ID, a1, superRegion);  
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+  
+  return R;
+}
+  
+//===----------------------------------------------------------------------===//
+// Traits for constructing regions.
+//===----------------------------------------------------------------------===//
+
+template <> struct MemRegionManagerTrait<CompoundLiteralRegion> {
+  typedef MemRegion SuperRegionTy;
+  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
+                                             const CompoundLiteralExpr *CL) {
+    
+    return CL->isFileScope() ? MRMgr.getGlobalsRegion() 
+                             : MRMgr.getStackRegion();
+  }
+};
+  
+template <> struct MemRegionManagerTrait<StringRegion> {
+  typedef MemSpaceRegion SuperRegionTy;
+  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
+                                             const StringLiteral*) {
+    return MRMgr.getGlobalsRegion();
+  }
+};
+  
+template <> struct MemRegionManagerTrait<VarRegion> {
+  typedef MemRegion SuperRegionTy;
+  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
+                                             const VarDecl *d) {
+    return d->hasLocalStorage() ? MRMgr.getStackRegion() 
+                                : MRMgr.getGlobalsRegion();
+  }
+};
+  
+template <> struct MemRegionManagerTrait<SymbolicRegion> {
+  typedef MemRegion SuperRegionTy;
+  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
+                                             SymbolRef) {
+    return MRMgr.getUnknownRegion();
+  }
+};
+  
+  
 } // end clang namespace
 
+//===----------------------------------------------------------------------===//
+// Pretty-printing regions.
+//===----------------------------------------------------------------------===//
+
 namespace llvm {
 static inline raw_ostream& operator<<(raw_ostream& O,
                                       const clang::MemRegion* R) { 
index 9e11a263536de3024d3476ad9d13170e49d2e9b0..68804b141b86872ce8b6cbddd52cbd7c792c28de 100644 (file)
@@ -18,6 +18,9 @@
 
 using namespace clang;
 
+//===----------------------------------------------------------------------===//
+// Basic methods.
+//===----------------------------------------------------------------------===//
 
 MemRegion::~MemRegion() {}
 
@@ -87,13 +90,15 @@ void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
   DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
 }
 
-void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym) {
+void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
+                                   const MemRegion *sreg) {
   ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
   ID.Add(sym);
+  ID.AddPointer(sreg);
 }
 
 void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
-  SymbolicRegion::ProfileRegion(ID, sym);
+  SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
 }
 
 void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -230,68 +235,21 @@ bool MemRegionManager::onHeap(const MemRegion* R) {
   return (R != 0) && (R == heap); 
 }
 
-StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
-  llvm::FoldingSetNodeID ID;
-  MemSpaceRegion* GlobalsR = getGlobalsRegion();
-
-  StringRegion::ProfileRegion(ID, Str, GlobalsR);
-
-  void* InsertPos;
-  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
-  StringRegion* R = cast_or_null<StringRegion>(data);
-
-  if (!R) {
-    R = (StringRegion*) A.Allocate<StringRegion>();
-    new (R) StringRegion(Str, GlobalsR);
-    Regions.InsertNode(R, InsertPos);
-  }
+//===----------------------------------------------------------------------===//
+// Constructing regions.
+//===----------------------------------------------------------------------===//
 
-  return R;
+StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
+  return getRegion<StringRegion>(Str);
 }
 
 VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
-  
-  const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion() 
-                                 : getGlobalsRegion();
-  
-  llvm::FoldingSetNodeID ID;
-  DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
-  
-  void* InsertPos;
-  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
-  VarRegion* R = cast_or_null<VarRegion>(data);
-  
-  if (!R) {
-    R = (VarRegion*) A.Allocate<VarRegion>();
-    new (R) VarRegion(d, superRegion);
-    Regions.InsertNode(R, InsertPos);
-  }
-  
-  return R;
+  return getRegion<VarRegion>(d);
 }
 
 CompoundLiteralRegion*
 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
-  // Is this compound literal allocated on the stack or is part of the
-  //  global constant pool?
-  const MemRegion* superRegion = CL->isFileScope() ?
-                                 getGlobalsRegion() : getStackRegion();
-
-  // Profile the compound literal.
-  llvm::FoldingSetNodeID ID;  
-  CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);  
-  
-  void* InsertPos;
-  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
-  CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
-  
-  if (!R) {
-    R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
-    new (R) CompoundLiteralRegion(CL, superRegion);
-    Regions.InsertNode(R, InsertPos);
-  }
-  
-  return R;
+  return getRegion<CompoundLiteralRegion>(CL);
 }
 
 ElementRegion*
@@ -351,20 +309,7 @@ CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
 
 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
 SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
-  llvm::FoldingSetNodeID ID;
-  SymbolicRegion::ProfileRegion(ID, sym);
-  void* InsertPos;
-  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
-  SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
-  
-  if (!R) {
-    R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
-    // SymbolicRegion's storage class is usually unknown.
-    new (R) SymbolicRegion(sym, getUnknownRegion());
-    Regions.InsertNode(R, InsertPos);
-  }
-  
-  return R;  
+  return getRegion<SymbolicRegion>(sym);
 }
 
 FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,