]> granicus.if.org Git - clang/commitdiff
Pull the region offset computation logic into a single method.
authorZhongxing Xu <xuzhongxing@gmail.com>
Tue, 3 Aug 2010 04:52:05 +0000 (04:52 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Tue, 3 Aug 2010 04:52:05 +0000 (04:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110102 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Checker/PathSensitive/MemRegion.h
lib/Checker/FlatStore.cpp
lib/Checker/MemRegion.cpp

index 79517925c873f1db1cb9246e7585695a28365d3a..82664adcb73fddccd28f6352f596f592ce75835a 100644 (file)
@@ -39,6 +39,22 @@ class ValueManager;
 class VarRegion;
 class CodeTextRegion;
 
+/// Represent a region's offset within the top level base region.
+class RegionOffset {
+  /// The base region.
+  const MemRegion *R;
+
+  /// The bit offset within the base region. It shouldn't be negative.
+  uint64_t Offset;
+
+public:
+  RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
+  RegionOffset(const MemRegion *r, uint64_t off) : R(r), Offset(off) {}
+
+  const MemRegion *getRegion() const { return R; }
+  uint64_t getOffset() const { return Offset; }
+};
+
 //===----------------------------------------------------------------------===//
 // Base region classes.
 //===----------------------------------------------------------------------===//
@@ -112,6 +128,9 @@ public:
   
   bool hasStackParametersStorage() const;
 
+  /// Compute the offset within the top level memory object.
+  RegionOffset getAsOffset() const;
+
   virtual void dumpToStream(llvm::raw_ostream& os) const;
 
   void dump() const;
@@ -262,21 +281,6 @@ public:
   }
 };
 
-/// Represent a region's offset within the top level base region.
-class RegionOffset {
-  /// The base region.
-  const MemRegion *R;
-
-  /// The bit offset within the base region. It shouldn't be negative.
-  uint64_t Offset;
-
-public:
-  RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
-  RegionOffset(const MemRegion *r, uint64_t off) : R(r), Offset(off) {}
-
-  const MemRegion *getRegion() const { return R; }
-  uint64_t getOffset() const { return Offset; }
-};
 
 /// SubRegion - A region that subsets another larger region.  Most regions
 ///  are subclasses of SubRegion.
@@ -294,11 +298,6 @@ public:
     return UnknownVal();
   }
 
-  /// Compute the offset within the top level memory object.
-  virtual RegionOffset getAsOffset() const {
-    llvm_unreachable("unimplemented");
-  }
-
   MemRegionManager* getMemRegionManager() const;
 
   bool isSubRegionOf(const MemRegion* R) const;
@@ -332,10 +331,6 @@ public:
 
   DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
@@ -552,10 +547,6 @@ public:
 
   DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -592,10 +583,6 @@ public:
 
   DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   bool isBoundable() const { return false; }
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
@@ -628,10 +615,6 @@ public:
     return C.getCanonicalType(CL->getType());
   }
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   bool isBoundable() const { return !CL->isFileScope(); }
 
   void Profile(llvm::FoldingSetNodeID& ID) const;
@@ -674,10 +657,6 @@ class VarRegion : public DeclRegion {
   VarRegion(const VarDecl* vd, const MemRegion* sReg)
     : DeclRegion(vd, sReg, VarRegionKind) {}
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
                             const MemRegion *superRegion) {
     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
@@ -722,10 +701,6 @@ public:
     return QualType(ThisPointerTy, 0);
   }
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   void dumpToStream(llvm::raw_ostream& os) const;
   
   static bool classof(const MemRegion* R) {
@@ -755,8 +730,6 @@ public:
 
   DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
 
-  virtual RegionOffset getAsOffset() const;
-
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
                             const MemRegion* superRegion) {
     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
@@ -845,8 +818,6 @@ public:
   /// Compute the offset within the array. The array might also be a subobject.
   RegionRawOffset getAsArrayOffset() const;
 
-  virtual RegionOffset getAsOffset() const;
-
   void dumpToStream(llvm::raw_ostream& os) const;
 
   void Profile(llvm::FoldingSetNodeID& ID) const;
@@ -873,10 +844,6 @@ public:
     return Ex->getType();
   }
 
-  virtual RegionOffset getAsOffset() const {
-    return RegionOffset(this, 0);
-  }
-
   void Profile(llvm::FoldingSetNodeID &ID) const;
 
   static bool classof(const MemRegion* R) {
index 51c537ecfadf04fb7ec22e2d1a7dd5a8be5bb275..e1683e5009c720f1f2b7365db0ef93fbcfe1f915 100644 (file)
@@ -192,14 +192,13 @@ FlatStoreManager::RegionToInterval(const MemRegion *R) {
 
   case MemRegion::ElementRegionKind: 
   case MemRegion::FieldRegionKind: {
-    const TypedRegion *TR = cast<TypedRegion>(R);
-    RegionOffset Offset = TR->getAsOffset();
-    // We cannot compute offset for all ElementRegions, for example, elements
+    RegionOffset Offset = R->getAsOffset();
+    // We cannot compute offset for all regions, for example, elements
     // with symbolic offsets.
     if (!Offset.getRegion())
       return RegionInterval(0, 0, 0);
     uint64_t Start = Offset.getOffset();
-    uint64_t Size = Ctx.getTypeSize(TR->getValueType(Ctx));
+    uint64_t Size = Ctx.getTypeSize(cast<TypedRegion>(R)->getValueType(Ctx));
     return RegionInterval(Offset.getRegion(), Start, Start+Size);
   }
 
index d9c559e84785f696752d85ad19bf752c8645f471..87eed2a2872791485a053a6e1036d6a4a9146bba 100644 (file)
@@ -828,48 +828,66 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const {
   return RegionRawOffset(superR, offset.getQuantity());
 }
 
-RegionOffset ElementRegion::getAsOffset() const {
-  uint64_t Offset;
-  if (const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Index)) {
-    int64_t i = CI->getValue().getSExtValue();
-    assert(i >= 0);
-    // We cannot compute offset for incomplete types.
-    if (!IsCompleteType(getContext(), ElementType))
-      return RegionOffset(0); 
-    
-    CharUnits Size = getContext().getTypeSizeInChars(ElementType);
-    Offset = i * Size.getQuantity() * 8;
-  } else
-    // We cannot compute offset for symbolic index.
-    return RegionOffset(0);
-
-  // Get the offset of the super region.
-  RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset();
-  if (!SOffset.getRegion())
-    return RegionOffset(0);
-  else
-    return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset);
-}
-
-RegionOffset FieldRegion::getAsOffset() const {
-  const RecordDecl *RD = getDecl()->getParent();
-  assert(RD->isDefinition());
-  // Get the field number.
-  unsigned idx = 0;
-  for (RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
-       FI != FE; ++FI, ++idx)
-    if (getDecl() == *FI)
+RegionOffset MemRegion::getAsOffset() const {
+  const MemRegion *R = this;
+  uint64_t Offset = 0;
+
+  while (1) {
+    switch (R->getKind()) {
+    default:
+      return RegionOffset(0);
+    case SymbolicRegionKind:
+    case AllocaRegionKind:
+    case CompoundLiteralRegionKind:
+    case CXXThisRegionKind:
+    case StringRegionKind:
+    case VarRegionKind:
+    case CXXObjectRegionKind:
+      goto Finish;
+    case ElementRegionKind: {
+      const ElementRegion *ER = cast<ElementRegion>(R);
+      QualType EleTy = ER->getValueType(getContext());
+
+      if (!IsCompleteType(getContext(), EleTy))
+        return RegionOffset(0);
+
+      SVal Index = ER->getIndex();
+      if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
+        int64_t i = CI->getValue().getSExtValue();
+        assert(i >= 0);
+        CharUnits Size = getContext().getTypeSizeInChars(EleTy);
+        Offset += i * Size.getQuantity() * 8;
+      } else {
+        // We cannot compute offset for non-concrete index.
+        return RegionOffset(0);
+      }
+      R = ER->getSuperRegion();
       break;
+    }
+    case FieldRegionKind: {
+      const FieldRegion *FR = cast<FieldRegion>(R);
+      const RecordDecl *RD = FR->getDecl()->getParent();
+      if (!RD->isDefinition())
+        // We cannot compute offset for incomplete type.
+        return RegionOffset(0);
+      // Get the field number.
+      unsigned idx = 0;
+      for (RecordDecl::field_iterator FI = RD->field_begin(), 
+             FE = RD->field_end(); FI != FE; ++FI, ++idx)
+        if (FR->getDecl() == *FI)
+          break;
 
-  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
-  // This is offset in bits.
-  uint64_t Offset = Layout.getFieldOffset(idx);
+      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+      // This is offset in bits.
+      Offset += Layout.getFieldOffset(idx);
+      R = FR->getSuperRegion();
+      break;
+    }
+    }
+  }
 
-  RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset();
-  if (!SOffset.getRegion())
-    return RegionOffset(0);
-  else
-    return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset);
+ Finish:
+  return RegionOffset(R, Offset);
 }
 
 //===----------------------------------------------------------------------===//