<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>