<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>This broke the build for me; it's not const-correct. Moreover, it's <i>really</i> not const-correct. A const ImmutableMapRef is the same as a const ImmutableMap::Factory: it means you're not going to try to generate new maps from it.</div><div><br></div><br><div><div>On Dec 7, 2012, at 11:54 , Ted Kremenek <<a href="mailto:kremenek@apple.com">kremenek@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Author: kremenek<br>Date: Fri Dec  7 13:54:25 2012<br>New Revision: 169630<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=169630&view=rev">http://llvm.org/viewvc/llvm-project?rev=169630&view=rev</a><br>Log:<br>Reduce conversions between Store <-> ImmutableMapRef in RegionStore.<br><br>This reduces canonicalization of ImmutableMaps.  This reduces analysis time<br>of one heavy Objective-C file by another 1%.<br><br>Modified:<br>    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp<br><br>Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=169630&r1=169629&r2=169630&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=169630&r1=169629&r2=169630&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)<br>+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Fri Dec  7 13:54:25 2012<br>@@ -155,28 +155,28 @@<br>     : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(P),<br>       CBFactory(CBFactory) {}<br><br>-  RegionBindingsRef add(key_type_ref K, data_type_ref D) {<br>-    return RegionBindingsRef(static_cast<ParentTy*>(this)->add(K, D),<br>+  RegionBindingsRef add(key_type_ref K, data_type_ref D) const {<br>+    return RegionBindingsRef(static_cast<const ParentTy*>(this)->add(K, D),<br>                              CBFactory);<br>   }<br><br>-  RegionBindingsRef remove(key_type_ref K) {<br>-    return RegionBindingsRef(static_cast<ParentTy*>(this)->remove(K),<br>+  RegionBindingsRef remove(key_type_ref K) const {<br>+    return RegionBindingsRef(static_cast<const ParentTy*>(this)->remove(K),<br>                              CBFactory);<br>   }<br><br>-  RegionBindingsRef addBinding(BindingKey K, SVal V);<br>+  RegionBindingsRef addBinding(BindingKey K, SVal V) const;<br><br>   RegionBindingsRef addBinding(const MemRegion *R,<br>-                               BindingKey::Kind k, SVal V);<br>+                               BindingKey::Kind k, SVal V) const;<br><br>   RegionBindingsRef &operator=(const RegionBindingsRef &X) {<br>     *static_cast<ParentTy*>(this) = X;<br>     return *this;<br>   }<br><br>-  const SVal *lookup(BindingKey K);<br>-  const SVal *lookup(const MemRegion *R, BindingKey::Kind k);<br>+  const SVal *lookup(BindingKey K) const;<br>+  const SVal *lookup(const MemRegion *R, BindingKey::Kind k) const;<br>   const ClusterBindings *lookup(const MemRegion *R) const {<br>     return static_cast<const ParentTy*>(this)->lookup(R);<br>   }<br>@@ -191,11 +191,11 @@<br>            removeBinding(R, BindingKey::Default);<br>   }<br><br>-  Optional<SVal> getDirectBinding(const MemRegion *R);<br>+  Optional<SVal> getDirectBinding(const MemRegion *R) const;<br><br>   /// getDefaultBinding - Returns an SVal* representing an optional default<br>   ///  binding associated with a region and its subregions.<br>-  Optional<SVal> getDefaultBinding(const MemRegion *R);<br>+  Optional<SVal> getDefaultBinding(const MemRegion *R) const;<br><br>   /// Return the internal tree as a Store.<br>   Store asStore() const {<br>@@ -204,13 +204,15 @@<br> };<br> } // end anonymous namespace<br><br>-Optional<SVal> RegionBindingsRef::getDirectBinding(const MemRegion *R) {<br>+typedef const RegionBindingsRef& RegionBindingsConstRef;<br>+<br>+Optional<SVal> RegionBindingsRef::getDirectBinding(const MemRegion *R) const {<br>   if (const SVal *V = lookup(R, BindingKey::Direct))<br>     return *V;<br>   return Optional<SVal>();<br> }<br><br>-Optional<SVal> RegionBindingsRef::getDefaultBinding(const MemRegion *R) {<br>+Optional<SVal> RegionBindingsRef::getDefaultBinding(const MemRegion *R) const {<br>   if (R->isBoundable())<br>     if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R))<br>       if (TR->getValueType()->isUnionType())<br>@@ -220,7 +222,7 @@<br>   return Optional<SVal>();<br> }<br><br>-RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K, SVal V) {<br>+RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K, SVal V) const {<br>   const MemRegion *Base = K.getBaseRegion();<br><br>   const ClusterBindings *ExistingCluster = lookup(Base);<br>@@ -234,11 +236,11 @@<br><br> RegionBindingsRef RegionBindingsRef::addBinding(const MemRegion *R,<br>                                                 BindingKey::Kind k,<br>-                                                SVal V) {<br>+                                                SVal V) const {<br>   return addBinding(BindingKey::Make(R, k), V);<br> }<br><br>-const SVal *RegionBindingsRef::lookup(BindingKey K) {<br>+const SVal *RegionBindingsRef::lookup(BindingKey K) const {<br>   const ClusterBindings *Cluster = lookup(K.getBaseRegion());<br>   if (!Cluster)<br>     return 0;<br>@@ -246,7 +248,7 @@<br> }<br><br> const SVal *RegionBindingsRef::lookup(const MemRegion *R,<br>-                                      BindingKey::Kind k) {<br>+                                      BindingKey::Kind k) const {<br>   return lookup(BindingKey::Make(R, k));<br> }<br><br>@@ -310,7 +312,8 @@<br>   /// setImplicitDefaultValue - Set the default binding for the provided<br>   ///  MemRegion to the value implicitly defined for compound literals when<br>   ///  the value is not specified.<br>-  StoreRef setImplicitDefaultValue(Store store, const MemRegion *R, QualType T);<br>+  RegionBindingsRef setImplicitDefaultValue(RegionBindingsConstRef B,<br>+                                            const MemRegion *R, QualType T);<br><br>   /// ArrayToPointer - Emulates the "decay" of an array to a pointer<br>   ///  type.  'Array' represents the lvalue of the array being decayed<br>@@ -344,12 +347,16 @@<br>   bool scanReachableSymbols(Store S, const MemRegion *R,<br>                             ScanReachableSymbols &Callbacks);<br><br>-  RegionBindingsRef removeSubRegionBindings(RegionBindingsRef B,<br>+  RegionBindingsRef removeSubRegionBindings(RegionBindingsConstRef B,<br>                                             const SubRegion *R);<br><br> public: // Part of public interface to class.<br><br>-  StoreRef Bind(Store store, Loc LV, SVal V);<br>+  virtual StoreRef Bind(Store store, Loc LV, SVal V) {<br>+    return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *this);<br>+  }<br>+<br>+  RegionBindingsRef bind(RegionBindingsConstRef B, Loc LV, SVal V);<br><br>   // BindDefault is only used to initialize a region with a default value.<br>   StoreRef BindDefault(Store store, const MemRegion *R, SVal V) {<br>@@ -376,21 +383,27 @@<br>                                const LocationContext *LC, SVal V);<br><br>   /// BindStruct - Bind a compound value to a structure.<br>-  StoreRef BindStruct(Store store, const TypedValueRegion* R, SVal V);<br>+  RegionBindingsRef bindStruct(RegionBindingsConstRef B,<br>+                               const TypedValueRegion* R, SVal V);<br><br>   /// BindVector - Bind a compound value to a vector.<br>-  StoreRef BindVector(Store store, const TypedValueRegion* R, SVal V);<br>+  RegionBindingsRef bindVector(RegionBindingsConstRef B,<br>+                               const TypedValueRegion* R, SVal V);<br><br>-  StoreRef BindArray(Store store, const TypedValueRegion* R, SVal V);<br>+  RegionBindingsRef bindArray(RegionBindingsConstRef B,<br>+                              const TypedValueRegion* R,<br>+                              SVal V);<br><br>   /// Clears out all bindings in the given region and assigns a new value<br>   /// as a Default binding.<br>-  StoreRef BindAggregate(Store store, const TypedRegion *R, SVal DefaultVal);<br>+  RegionBindingsRef bindAggregate(RegionBindingsConstRef B,<br>+                                  const TypedRegion *R,<br>+                                  SVal DefaultVal);<br><br>   /// \brief Create a new store with the specified binding removed.<br>   /// \param ST the original store, that is the basis for the new store.<br>   /// \param L the location whose binding should be removed.<br>-  StoreRef killBinding(Store ST, Loc L);<br>+  virtual StoreRef killBinding(Store ST, Loc L);<br><br>   void incrementReferenceCount(Store store) {<br>     getRegionBindings(store).manualRetain();    <br>@@ -418,43 +431,49 @@<br>   ///       return undefined<br>   ///     else<br>   ///       return symbolic<br>-  SVal getBinding(Store store, Loc L, QualType T = QualType());<br>+  virtual SVal getBinding(Store S, Loc L, QualType T) {<br>+    return getBinding(getRegionBindings(S), L, T);<br>+  }<br>+<br>+  SVal getBinding(RegionBindingsConstRef B, Loc L, QualType T = QualType());<br><br>-  SVal getBindingForElement(Store store, const ElementRegion *R);<br>+  SVal getBindingForElement(RegionBindingsConstRef B, const ElementRegion *R);<br><br>-  SVal getBindingForField(Store store, const FieldRegion *R);<br>+  SVal getBindingForField(RegionBindingsConstRef B, const FieldRegion *R);<br><br>-  SVal getBindingForObjCIvar(Store store, const ObjCIvarRegion *R);<br>+  SVal getBindingForObjCIvar(RegionBindingsConstRef B, const ObjCIvarRegion *R);<br><br>-  SVal getBindingForVar(Store store, const VarRegion *R);<br>+  SVal getBindingForVar(RegionBindingsConstRef B, const VarRegion *R);<br><br>   SVal getBindingForLazySymbol(const TypedValueRegion *R);<br><br>-  SVal getBindingForFieldOrElementCommon(Store store, const TypedValueRegion *R,<br>-                                         QualType Ty, const MemRegion *superR);<br>+  SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,<br>+                                         const TypedValueRegion *R,<br>+                                         QualType Ty,<br>+                                         const MemRegion *superR);<br><br>-  SVal getLazyBinding(const MemRegion *lazyBindingRegion,<br>-                      Store lazyBindingStore);<br>+  SVal getLazyBinding(const MemRegion *LazyBindingRegion,<br>+                      RegionBindingsRef LazyBinding);<br><br>   /// Get bindings for the values in a struct and return a CompoundVal, used<br>   /// when doing struct copy:<br>   /// struct s x, y;<br>   /// x = y;<br>   /// y's value is retrieved by this method.<br>-  SVal getBindingForStruct(Store store, const TypedValueRegion* R);<br>+  SVal getBindingForStruct(RegionBindingsConstRef B, const TypedValueRegion* R);<br><br>-  SVal getBindingForArray(Store store, const TypedValueRegion* R);<br>+  SVal getBindingForArray(RegionBindingsConstRef B, const TypedValueRegion* R);<br><br>   /// Used to lazily generate derived symbols for bindings that are defined<br>   ///  implicitly by default bindings in a super region.<br>-  Optional<SVal> getBindingForDerivedDefaultValue(RegionBindingsRef B,<br>+  Optional<SVal> getBindingForDerivedDefaultValue(RegionBindingsConstRef B,<br>                                                   const MemRegion *superR,<br>                                                   const TypedValueRegion *R,<br>                                                   QualType Ty);<br><br>   /// Get the state and region whose binding this region R corresponds to.<br>   std::pair<Store, const MemRegion*><br>-  getLazyBinding(RegionBindingsRef B, const MemRegion *R,<br>+  getLazyBinding(RegionBindingsConstRef B, const MemRegion *R,<br>                  const MemRegion *originalRegion,<br>                  bool includeSuffix = false);<br><br>@@ -677,7 +696,7 @@<br> }<br><br> RegionBindingsRef<br>-RegionStoreManager::removeSubRegionBindings(RegionBindingsRef B,<br>+RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,<br>                                             const SubRegion *R) {<br>   BindingKey SRKey = BindingKey::Make(R, BindingKey::Default);<br>   const MemRegion *ClusterHead = SRKey.getBaseRegion();<br>@@ -865,8 +884,7 @@<br>         // invalidate that region.  This is because a block may capture<br>         // a pointer value, but the thing pointed by that pointer may<br>         // get invalidated.<br>-        Store store = B.asStore();<br>-        SVal V = RM.getBinding(store, loc::MemRegionVal(VR));<br>+        SVal V = RM.getBinding(B, loc::MemRegionVal(VR));<br>         if (const Loc *L = dyn_cast<Loc>(&V)) {<br>           if (const MemRegion *LR = L->getAsRegion())<br>             AddToWorkList(LR);<br>@@ -1062,7 +1080,7 @@<br> // Loading values from regions.<br> //===----------------------------------------------------------------------===//<br><br>-SVal RegionStoreManager::getBinding(Store store, Loc L, QualType T) {<br>+SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) {<br>   assert(!isa<UnknownVal>(L) && "location unknown");<br>   assert(!isa<UndefinedVal>(L) && "location undefined");<br><br>@@ -1108,9 +1126,8 @@<br>   //   char c = *q;  // returns the first byte of 'x'.<br>   //<br>   // Such funny addressing will occur due to layering of regions.<br>-<br>   if (RTy->isStructureOrClassType())<br>-    return getBindingForStruct(store, R);<br>+    return getBindingForStruct(B, R);<br><br>   // FIXME: Handle unions.<br>   if (RTy->isUnionType())<br>@@ -1118,7 +1135,7 @@<br><br>   if (RTy->isArrayType()) {<br>     if (RTy->isConstantArrayType())<br>-      return getBindingForArray(store, R);<br>+      return getBindingForArray(B, R);<br>     else<br>       return UnknownVal();<br>   }<br>@@ -1128,7 +1145,7 @@<br>     return UnknownVal();<br><br>   if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))<br>-    return CastRetrievedVal(getBindingForField(store, FR), FR, T, false);<br>+    return CastRetrievedVal(getBindingForField(B, FR), FR, T, false);<br><br>   if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {<br>     // FIXME: Here we actually perform an implicit conversion from the loaded<br>@@ -1136,7 +1153,7 @@<br>     // more intelligently.  For example, an 'element' can encompass multiple<br>     // bound regions (e.g., several bound bytes), or could be a subset of<br>     // a larger value.<br>-    return CastRetrievedVal(getBindingForElement(store, ER), ER, T, false);<br>+    return CastRetrievedVal(getBindingForElement(B, ER), ER, T, false);<br>   }<br><br>   if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {<br>@@ -1146,7 +1163,7 @@<br>     // reinterpretted, it is possible we stored a different value that could<br>     // fit within the ivar.  Either we need to cast these when storing them<br>     // or reinterpret them lazily (as we do here).<br>-    return CastRetrievedVal(getBindingForObjCIvar(store, IVR), IVR, T, false);<br>+    return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T, false);<br>   }<br><br>   if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {<br>@@ -1156,10 +1173,9 @@<br>     // variable is reinterpretted, it is possible we stored a different value<br>     // that could fit within the variable.  Either we need to cast these when<br>     // storing them or reinterpret them lazily (as we do here).<br>-    return CastRetrievedVal(getBindingForVar(store, VR), VR, T, false);<br>+    return CastRetrievedVal(getBindingForVar(B, VR), VR, T, false);<br>   }<br><br>-  RegionBindingsRef B = getRegionBindings(store);<br>   const SVal *V = B.lookup(R, BindingKey::Direct);<br><br>   // Check if the region has a binding.<br>@@ -1182,7 +1198,7 @@<br> }<br><br> std::pair<Store, const MemRegion *><br>-RegionStoreManager::getLazyBinding(RegionBindingsRef B,<br>+RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,<br>                                    const MemRegion *R,<br>                                    const MemRegion *originalRegion,<br>                                    bool includeSuffix) {<br>@@ -1236,14 +1252,13 @@<br>   return std::make_pair((Store) 0, (const MemRegion *) 0);<br> }<br><br>-SVal RegionStoreManager::getBindingForElement(Store store,<br>+SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,<br>                                               const ElementRegion* R) {<br>   // We do not currently model bindings of the CompoundLiteralregion.<br>   if (isa<CompoundLiteralRegion>(R->getBaseRegion()))<br>     return UnknownVal();<br><br>   // Check if the region has a binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br>   if (const Optional<SVal> &V = B.getDirectBinding(R))<br>     return *V;<br><br>@@ -1312,24 +1327,23 @@<br>       }<br>     }<br>   }<br>-  return getBindingForFieldOrElementCommon(store, R, R->getElementType(),<br>+  return getBindingForFieldOrElementCommon(B, R, R->getElementType(),<br>                                            superR);<br> }<br><br>-SVal RegionStoreManager::getBindingForField(Store store,<br>-                                       const FieldRegion* R) {<br>+SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,<br>+                                            const FieldRegion* R) {<br><br>   // Check if the region has a binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br>   if (const Optional<SVal> &V = B.getDirectBinding(R))<br>     return *V;<br><br>   QualType Ty = R->getValueType();<br>-  return getBindingForFieldOrElementCommon(store, R, Ty, R->getSuperRegion());<br>+  return getBindingForFieldOrElementCommon(B, R, Ty, R->getSuperRegion());<br> }<br><br> Optional<SVal><br>-RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsRef B,<br>+RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,<br>                                                      const MemRegion *superR,<br>                                                      const TypedValueRegion *R,<br>                                                      QualType Ty) {<br>@@ -1355,32 +1369,30 @@<br>   return Optional<SVal>();<br> }<br><br>-SVal RegionStoreManager::getLazyBinding(const MemRegion *lazyBindingRegion,<br>-                                        Store lazyBindingStore) {<br>-  if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion))<br>-    return getBindingForElement(lazyBindingStore, ER);<br>-  <br>-  return getBindingForField(lazyBindingStore,<br>-                            cast<FieldRegion>(lazyBindingRegion));<br>+SVal RegionStoreManager::getLazyBinding(const MemRegion *LazyBindingRegion,<br>+                                        RegionBindingsRef LazyBinding) {<br>+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))<br>+    return getBindingForElement(LazyBinding, ER);<br>+  return getBindingForField(LazyBinding, cast<FieldRegion>(LazyBindingRegion));<br> }<br><br>-SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store,<br>+SVal<br>+RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,<br>                                                       const TypedValueRegion *R,<br>                                                       QualType Ty,<br>                                                       const MemRegion *superR) {<br><br>   // At this point we have already checked in either getBindingForElement or<br>   // getBindingForField if 'R' has a direct binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br><br>   // Lazy binding?<br>   Store lazyBindingStore = NULL;<br>   const MemRegion *lazyBindingRegion = NULL;<br>   llvm::tie(lazyBindingStore, lazyBindingRegion) = getLazyBinding(B, R, R,<br>                                                                   true);<br>-  <br>   if (lazyBindingRegion)<br>-    return getLazyBinding(lazyBindingRegion, lazyBindingStore);<br>+    return getLazyBinding(lazyBindingRegion,<br>+                          getRegionBindings(lazyBindingStore));<br><br>   // Record whether or not we see a symbolic index.  That can completely<br>   // be out of scope of our lookup.<br>@@ -1431,12 +1443,9 @@<br>   return svalBuilder.getRegionValueSymbolVal(R);<br> }<br><br>-SVal RegionStoreManager::getBindingForObjCIvar(Store store,<br>+SVal RegionStoreManager::getBindingForObjCIvar(RegionBindingsConstRef B,<br>                                                const ObjCIvarRegion* R) {<br>-<br>-    // Check if the region has a binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br>-<br>+  // Check if the region has a binding.<br>   if (const Optional<SVal> &V = B.getDirectBinding(R))<br>     return *V;<br><br>@@ -1454,11 +1463,10 @@<br>   return getBindingForLazySymbol(R);<br> }<br><br>-SVal RegionStoreManager::getBindingForVar(Store store, const VarRegion *R) {<br>+SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,<br>+                                          const VarRegion *R) {<br><br>   // Check if the region has a binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br>-<br>   if (const Optional<SVal> &V = B.getDirectBinding(R))<br>     return *V;<br><br>@@ -1513,8 +1521,8 @@<br>   return Ty->isArrayType() || Ty->isStructureOrClassType();<br> }<br><br>-SVal RegionStoreManager::getBindingForStruct(Store store, <br>-                                        const TypedValueRegion* R) {<br>+SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B,<br>+                                             const TypedValueRegion* R) {<br>   const RecordDecl *RD = R->getValueType()->castAs<RecordType>()->getDecl();<br>   if (RD->field_empty())<br>     return UnknownVal();<br>@@ -1524,7 +1532,6 @@<br>   // (Right now we can't tell the difference.)<br>   QualType FirstFieldType = RD->field_begin()->getType();<br>   if (!mayHaveLazyBinding(FirstFieldType)) {<br>-    RegionBindingsRef B = getRegionBindings(store);<br>     BindingKey K = BindingKey::Make(R, BindingKey::Default);<br>     if (const nonloc::LazyCompoundVal *V =<br>           dyn_cast_or_null<nonloc::LazyCompoundVal>(B.lookup(K))) {<br>@@ -1532,11 +1539,11 @@<br>     }<br>   }<br><br>-  return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R);<br>+  return svalBuilder.makeLazyCompoundVal(StoreRef(B.asStore(), *this), R);<br> }<br><br>-SVal RegionStoreManager::getBindingForArray(Store store,<br>-                                       const TypedValueRegion * R) {<br>+SVal RegionStoreManager::getBindingForArray(RegionBindingsConstRef B,<br>+                                            const TypedValueRegion * R) {<br>   const ConstantArrayType *Ty = Ctx.getAsConstantArrayType(R->getValueType());<br>   assert(Ty && "Only constant array types can have compound bindings.");<br><br>@@ -1544,7 +1551,6 @@<br>   // unless the first element might have a lazy binding of its own.<br>   // (Right now we can't tell the difference.)<br>   if (!mayHaveLazyBinding(Ty->getElementType())) {<br>-    RegionBindingsRef B = getRegionBindings(store);<br>     BindingKey K = BindingKey::Make(R, BindingKey::Default);<br>     if (const nonloc::LazyCompoundVal *V =<br>         dyn_cast_or_null<nonloc::LazyCompoundVal>(B.lookup(K))) {<br>@@ -1552,7 +1558,7 @@<br>     }<br>   }<br><br>-  return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R);<br>+  return svalBuilder.makeLazyCompoundVal(StoreRef(B.asStore(), *this), R);<br> }<br><br> bool RegionStoreManager::includedInBindings(Store store,<br>@@ -1594,9 +1600,10 @@<br>   return StoreRef(ST, *this);<br> }<br><br>-StoreRef RegionStoreManager::Bind(Store store, Loc L, SVal V) {<br>+RegionBindingsRef<br>+RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {<br>   if (isa<loc::ConcreteInt>(L))<br>-    return StoreRef(store, *this);<br>+    return B;<br><br>   // If we get here, the location should be a region.<br>   const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();<br>@@ -1605,11 +1612,11 @@<br>   if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) {<br>     QualType Ty = TR->getValueType();<br>     if (Ty->isArrayType())<br>-      return BindArray(store, TR, V);<br>+      return bindArray(B, TR, V);<br>     if (Ty->isStructureOrClassType())<br>-      return BindStruct(store, TR, V);<br>+      return bindStruct(B, TR, V);<br>     if (Ty->isVectorType())<br>-      return BindVector(store, TR, V);<br>+      return bindVector(B, TR, V);<br>   }<br><br>   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {<br>@@ -1623,13 +1630,8 @@<br>   }<br><br>   // Clear out bindings that may overlap with this binding.<br>-<br>-  // Perform the binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br>-  B = removeSubRegionBindings(B, cast<SubRegion>(R));<br>-  BindingKey Key = BindingKey::Make(R, BindingKey::Direct);<br>-  return StoreRef(B.addBinding(Key, V).asStore(),<br>-                  *this);<br>+  RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));<br>+  return NewB.addBinding(BindingKey::Make(R, BindingKey::Direct), V);<br> }<br><br> // FIXME: this method should be merged into Bind().<br>@@ -1640,10 +1642,10 @@<br>   return Bind(ST, loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC)), V);<br> }<br><br>-StoreRef RegionStoreManager::setImplicitDefaultValue(Store store,<br>-                                                     const MemRegion *R,<br>-                                                     QualType T) {<br>-  RegionBindingsRef B = getRegionBindings(store);<br>+RegionBindingsRef<br>+RegionStoreManager::setImplicitDefaultValue(RegionBindingsConstRef B,<br>+                                            const MemRegion *R,<br>+                                            QualType T) {<br>   SVal V;<br><br>   if (Loc::isLocType(T))<br>@@ -1664,12 +1666,13 @@<br>     V = UnknownVal();<br>   }<br><br>-  return StoreRef(B.addBinding(R, BindingKey::Default, V)<br>-                   .asStore(), *this);<br>+  return B.addBinding(R, BindingKey::Default, V);<br> }<br><br>-StoreRef RegionStoreManager::BindArray(Store store, const TypedValueRegion* R,<br>-                                       SVal Init) {<br>+RegionBindingsRef<br>+RegionStoreManager::bindArray(RegionBindingsConstRef B,<br>+                              const TypedValueRegion* R,<br>+                              SVal Init) {<br><br>   const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));<br>   QualType ElementTy = AT->getElementType();<br>@@ -1683,26 +1686,27 @@<br>     const StringRegion *S = cast<StringRegion>(MRV->getRegion());<br><br>     // Treat the string as a lazy compound value.<br>+    StoreRef store(B.asStore(), *this);<br>     nonloc::LazyCompoundVal LCV =<br>-      cast<nonloc::LazyCompoundVal>(svalBuilder.<br>-                                makeLazyCompoundVal(StoreRef(store, *this), S));<br>-    return BindAggregate(store, R, LCV);<br>+      cast<nonloc::LazyCompoundVal>(svalBuilder.makeLazyCompoundVal(store, S));<br>+    return bindAggregate(B, R, LCV);<br>   }<br><br>   // Handle lazy compound values.<br>   if (isa<nonloc::LazyCompoundVal>(Init))<br>-    return BindAggregate(store, R, Init);<br>+    return bindAggregate(B, R, Init);<br><br>   // Remaining case: explicit compound values.<br><br>   if (Init.isUnknown())<br>-    return setImplicitDefaultValue(store, R, ElementTy);<br>+    return setImplicitDefaultValue(B, R, ElementTy);<br><br>   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);<br>   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();<br>   uint64_t i = 0;<br><br>-  StoreRef newStore(store, *this);<br>+  RegionBindingsRef NewB(B);<br>+<br>   for (; Size.hasValue() ? i < Size.getValue() : true ; ++i, ++VI) {<br>     // The init list might be shorter than the array length.<br>     if (VI == VE)<br>@@ -1712,44 +1716,45 @@<br>     const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);<br><br>     if (ElementTy->isStructureOrClassType())<br>-      newStore = BindStruct(newStore.getStore(), ER, *VI);<br>+      NewB = bindStruct(NewB, ER, *VI);<br>     else if (ElementTy->isArrayType())<br>-      newStore = BindArray(newStore.getStore(), ER, *VI);<br>+      NewB = bindArray(NewB, ER, *VI);<br>     else<br>-      newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(ER), *VI);<br>+      NewB = bind(NewB, svalBuilder.makeLoc(ER), *VI);<br>   }<br><br>   // If the init list is shorter than the array length, set the<br>   // array default value.<br>   if (Size.hasValue() && i < Size.getValue())<br>-    newStore = setImplicitDefaultValue(newStore.getStore(), R, ElementTy);<br>+    NewB = setImplicitDefaultValue(NewB, R, ElementTy);<br><br>-  return newStore;<br>+  return NewB;<br> }<br><br>-StoreRef RegionStoreManager::BindVector(Store store, const TypedValueRegion* R,<br>-                                        SVal V) {<br>+RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,<br>+                                                 const TypedValueRegion* R,<br>+                                                 SVal V) {<br>   QualType T = R->getValueType();<br>   assert(T->isVectorType());<br>   const VectorType *VT = T->getAs<VectorType>(); // Use getAs for typedefs.<br><br>   // Handle lazy compound values and symbolic values.<br>   if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))<br>-    return BindAggregate(store, R, V);<br>+    return bindAggregate(B, R, V);<br><br>   // We may get non-CompoundVal accidentally due to imprecise cast logic or<br>   // that we are binding symbolic struct value. Kill the field values, and if<br>   // the value is symbolic go and bind it as a "default" binding.<br>   if (!isa<nonloc::CompoundVal>(V)) {<br>-    return BindAggregate(store, R, UnknownVal());<br>+    return bindAggregate(B, R, UnknownVal());<br>   }<br><br>   QualType ElemType = VT->getElementType();<br>   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);<br>   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();<br>   unsigned index = 0, numElements = VT->getNumElements();<br>-  StoreRef newStore(store, *this);<br>-  <br>+  RegionBindingsRef NewB(B);<br>+<br>   for ( ; index != numElements ; ++index) {<br>     if (VI == VE)<br>       break;<br>@@ -1758,20 +1763,20 @@<br>     const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);<br><br>     if (ElemType->isArrayType())<br>-      newStore = BindArray(newStore.getStore(), ER, *VI);<br>+      NewB = bindArray(NewB, ER, *VI);<br>     else if (ElemType->isStructureOrClassType())<br>-      newStore = BindStruct(newStore.getStore(), ER, *VI);<br>+      NewB = bindStruct(NewB, ER, *VI);<br>     else<br>-      newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(ER), *VI);<br>+      NewB = bind(NewB, svalBuilder.makeLoc(ER), *VI);<br>   }<br>-  return newStore;<br>+  return NewB;<br> }<br><br>-StoreRef RegionStoreManager::BindStruct(Store store, const TypedValueRegion* R,<br>-                                        SVal V) {<br>-<br>+RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,<br>+                                                 const TypedValueRegion* R,<br>+                                                 SVal V) {<br>   if (!Features.supportsFields())<br>-    return StoreRef(store, *this);<br>+    return B;<br><br>   QualType T = R->getValueType();<br>   assert(T->isStructureOrClassType());<br>@@ -1780,24 +1785,24 @@<br>   RecordDecl *RD = RT->getDecl();<br><br>   if (!RD->isCompleteDefinition())<br>-    return StoreRef(store, *this);<br>+    return B;<br><br>   // Handle lazy compound values and symbolic values.<br>   if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))<br>-    return BindAggregate(store, R, V);<br>+    return bindAggregate(B, R, V);<br><br>   // We may get non-CompoundVal accidentally due to imprecise cast logic or<br>   // that we are binding symbolic struct value. Kill the field values, and if<br>   // the value is symbolic go and bind it as a "default" binding.<br>   if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))<br>-    return BindAggregate(store, R, UnknownVal());<br>+    return bindAggregate(B, R, UnknownVal());<br><br>   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);<br>   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();<br><br>   RecordDecl::field_iterator FI, FE;<br>-  StoreRef newStore(store, *this);<br>-  <br>+  RegionBindingsRef NewB(B);<br>+<br>   for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {<br><br>     if (VI == VE)<br>@@ -1811,31 +1816,30 @@<br>     const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);<br><br>     if (FTy->isArrayType())<br>-      newStore = BindArray(newStore.getStore(), FR, *VI);<br>+      NewB = bindArray(NewB, FR, *VI);<br>     else if (FTy->isStructureOrClassType())<br>-      newStore = BindStruct(newStore.getStore(), FR, *VI);<br>+      NewB = bindStruct(NewB, FR, *VI);<br>     else<br>-      newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(FR), *VI);<br>+      NewB = bind(NewB, svalBuilder.makeLoc(FR), *VI);<br>     ++VI;<br>   }<br><br>   // There may be fewer values in the initialize list than the fields of struct.<br>   if (FI != FE) {<br>-    RegionBindingsRef B = getRegionBindings(newStore.getStore());<br>-    B = B.addBinding(R, BindingKey::Default, svalBuilder.makeIntVal(0, false));<br>-    newStore = StoreRef(B.asStore(), *this);<br>+    NewB = NewB.addBinding(R, BindingKey::Default,<br>+                           svalBuilder.makeIntVal(0, false));<br>   }<br><br>-  return newStore;<br>+  return NewB;<br> }<br><br>-StoreRef RegionStoreManager::BindAggregate(Store store, const TypedRegion *R,<br>-                                           SVal Val) {<br>+RegionBindingsRef<br>+RegionStoreManager::bindAggregate(RegionBindingsConstRef B,<br>+                                  const TypedRegion *R,<br>+                                  SVal Val) {<br>   // Remove the old bindings, using 'R' as the root of all regions<br>   // we will invalidate. Then add the new binding.<br>-  RegionBindingsRef B = getRegionBindings(store);<br>-  B = removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val);<br>-  return StoreRef(B.asStore(), *this);<br>+  return removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val);<br> }<br><br> //===----------------------------------------------------------------------===//<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></blockquote></div><br></body></html>