diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp
index 682feb5..388b2e9 100644
--- a/clang/lib/Analysis/BasicStore.cpp
+++ b/clang/lib/Analysis/BasicStore.cpp
@@ -20,10 +20,10 @@
 
 using namespace clang;
 
-typedef llvm::ImmutableMap<const MemRegion*,SVal> BindingsTy;  
+typedef llvm::ImmutableMap<const MemRegion*,SVal> BindingsTy;
 
 namespace {
-  
+
 class VISIBILITY_HIDDEN BasicStoreSubRegionMap : public SubRegionMap {
 public:
   BasicStoreSubRegionMap() {}
@@ -32,13 +32,13 @@
     return true; // Do nothing.  No subregions.
   }
 };
-  
+
 class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
   BindingsTy::Factory VBFactory;
 public:
   BasicStoreManager(GRStateManager& mgr)
     : StoreManager(mgr), VBFactory(mgr.getAllocator()) {}
-  
+
   ~BasicStoreManager() {}
 
   SubRegionMap *getSubRegionMap(const GRState *state) {
@@ -47,7 +47,7 @@
 
   SValuator::CastResult Retrieve(const GRState *state, Loc loc,
                                  QualType T = QualType());
-  
+
   const GRState *InvalidateRegion(const GRState *state, const MemRegion *R,
                                   const Expr *E, unsigned Count);
 
@@ -57,8 +57,8 @@
 
   Store scanForIvars(Stmt *B, const Decl* SelfDecl,
                      const MemRegion *SelfRegion, Store St);
-  
-  Store BindInternal(Store St, Loc loc, SVal V);  
+
+  Store BindInternal(Store St, Loc loc, SVal V);
   Store Remove(Store St, Loc loc);
   Store getInitialStore(const LocationContext *InitLoc);
 
@@ -66,27 +66,27 @@
   virtual Loc getLoc(const VarDecl* VD, const LocationContext *LC) {
     return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
   }
-  
+
   const GRState *BindCompoundLiteral(const GRState *state,
                                      const CompoundLiteralExpr* cl,
                                      SVal val) {
     return state;
   }
-  
+
   SVal getLValueVar(const GRState *state, const VarDecl *VD,
                     const LocationContext *LC);
   SVal getLValueString(const GRState *state, const StringLiteral *S);
   SVal getLValueCompoundLiteral(const GRState *state,
                                 const CompoundLiteralExpr *CL);
   SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
-  SVal getLValueField(const GRState *state, SVal Base, const FieldDecl *D);  
+  SVal getLValueField(const GRState *state, SVal Base, const FieldDecl *D);
   SVal getLValueElement(const GRState *state, QualType elementType,
                         SVal Base, SVal Offset);
 
   /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
   ///  conversions between arrays and pointers.
   SVal ArrayToPointer(Loc Array) { return Array; }
-    
+
   /// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
   ///  It updatees the GRState object in place with the values removed.
   void RemoveDeadBindings(GRState &state, Stmt* Loc, SymbolReaper& SymReaper,
@@ -118,7 +118,7 @@
 private:
   ASTContext& getContext() { return StateMgr.getContext(); }
 };
-    
+
 } // end anonymous namespace
 
 
@@ -131,7 +131,7 @@
   return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
 }
 
-SVal BasicStoreManager::getLValueString(const GRState *state, 
+SVal BasicStoreManager::getLValueString(const GRState *state,
                                         const StringLiteral* S) {
   return ValMgr.makeLoc(MRMgr.getStringRegion(S));
 }
@@ -144,7 +144,7 @@
 SVal BasicStoreManager::getLValueIvar(const GRState *state,
                                       const ObjCIvarDecl* D,
                                       SVal Base) {
-  
+
   if (Base.isUnknownOrUndef())
     return Base;
 
@@ -154,7 +154,7 @@
     const MemRegion *BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
     return ValMgr.makeLoc(MRMgr.getObjCIvarRegion(D, BaseR));
   }
-  
+
   return UnknownVal();
 }
 
@@ -163,10 +163,10 @@
 
   if (Base.isUnknownOrUndef())
     return Base;
-  
-  Loc BaseL = cast<Loc>(Base);  
+
+  Loc BaseL = cast<Loc>(Base);
   const MemRegion* BaseR = 0;
-  
+
   switch(BaseL.getSubKind()) {
     case loc::GotoLabelKind:
       return UndefinedVal();
@@ -174,7 +174,7 @@
     case loc::MemRegionKind:
       BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
       break;
-      
+
     case loc::ConcreteIntKind:
       // While these seem funny, this can happen through casts.
       // FIXME: What we should return is the field offset.  For example,
@@ -186,7 +186,7 @@
       assert ("Unhandled Base.");
       return Base;
   }
-  
+
   return ValMgr.makeLoc(MRMgr.getFieldRegion(D, BaseR));
 }
 
@@ -196,18 +196,18 @@
 
   if (Base.isUnknownOrUndef())
     return Base;
-  
-  Loc BaseL = cast<Loc>(Base);  
+
+  Loc BaseL = cast<Loc>(Base);
   const MemRegion* BaseR = 0;
-  
+
   switch(BaseL.getSubKind()) {
     case loc::GotoLabelKind:
       // Technically we can get here if people do funny things with casts.
       return UndefinedVal();
-      
+
     case loc::MemRegionKind: {
       const MemRegion *R = cast<loc::MemRegionVal>(BaseL).getRegion();
-      
+
       if (isa<ElementRegion>(R)) {
         // int x;
         // char* y = (char*) &x;
@@ -215,12 +215,12 @@
         // y[0] = 'a';
         return Base;
       }
-      
+
       if (isa<TypedRegion>(R) || isa<SymbolicRegion>(R)) {
         BaseR = R;
         break;
       }
-      
+
       break;
     }
 
@@ -230,13 +230,13 @@
       //  add the field offset to the integer value.  That way funny things
       //  like this work properly:  &(((struct foo *) 0xa)->f)
       return Base;
-      
+
     default:
       assert ("Unhandled Base.");
       return Base;
   }
-  
-  if (BaseR) { 
+
+  if (BaseR) {
     return ValMgr.makeLoc(MRMgr.getElementRegion(elementType, UnknownVal(),
                                                  BaseR, getContext()));
   }
@@ -246,38 +246,38 @@
 
 static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
   bool foundPointer = false;
-  while (1) {  
+  while (1) {
     const PointerType *PT = T->getAs<PointerType>();
     if (!PT) {
       if (!foundPointer)
         return false;
-      
+
       // intptr_t* or intptr_t**, etc?
       if (T->isIntegerType() && C.getTypeSize(T) == C.getTypeSize(C.VoidPtrTy))
         return true;
-      
+
       QualType X = C.getCanonicalType(T).getUnqualifiedType();
       return X == C.VoidTy;
     }
-    
+
     foundPointer = true;
     T = PT->getPointeeType();
-  }  
+  }
 }
- 
+
 SValuator::CastResult BasicStoreManager::Retrieve(const GRState *state,
                                                   Loc loc, QualType T) {
-  
+
   if (isa<UnknownVal>(loc))
     return SValuator::CastResult(state, UnknownVal());
-  
+
   assert(!isa<UndefinedVal>(loc));
-  
+
   switch (loc.getSubKind()) {
 
     case loc::MemRegionKind: {
       const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
-      
+
       if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
         // Just support void**, void***, intptr_t*, intptr_t**, etc., for now.
         // This is needed to handle OSCompareAndSwapPtr() and friends.
@@ -286,45 +286,45 @@
 
         if (!isHigherOrderRawPtr(T, Ctx))
           return SValuator::CastResult(state, UnknownVal());
-        
+
         // FIXME: Should check for element 0.
         // Otherwise, strip the element region.
         R = ER->getSuperRegion();
       }
-      
+
       if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
         return SValuator::CastResult(state, UnknownVal());
-      
+
       BindingsTy B = GetBindings(state->getStore());
       BindingsTy::data_type *Val = B.lookup(R);
-      
+
       if (!Val)
         break;
-      
+
       return CastRetrievedVal(*Val, state, cast<TypedRegion>(R), T);
     }
-      
+
     case loc::ConcreteIntKind:
       // Some clients may call GetSVal with such an option simply because
       // they are doing a quick scan through their Locs (potentially to
       // invalidate their bindings).  Just return Undefined.
       return SValuator::CastResult(state, UndefinedVal());
-      
+
     default:
       assert (false && "Invalid Loc.");
       break;
   }
-  
+
   return SValuator::CastResult(state, UnknownVal());
 }
-  
-Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {    
+
+Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {
   if (isa<loc::ConcreteInt>(loc))
     return store;
 
   const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
   ASTContext &C = StateMgr.getContext();
-      
+
   // Special case: handle store of pointer values (Loc) to pointers via
   // a cast to intXX_t*, void*, etc.  This is needed to handle
   // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
@@ -332,20 +332,20 @@
     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
       // FIXME: Should check for index 0.
       QualType T = ER->getLocationType(C);
-        
+
       if (isHigherOrderRawPtr(T, C))
         R = ER->getSuperRegion();
-    }      
-      
+    }
+
   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
     return store;
 
   const TypedRegion *TyR = cast<TypedRegion>(R);
-  
+
   // Do not bind to arrays.  We need to explicitly check for this so that
   // we do not encounter any weirdness of trying to load/store from arrays.
   if (TyR->isBoundable() && TyR->getValueType(C)->isArrayType())
-    return store;  
+    return store;
 
   if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
     // Only convert 'V' to a location iff the underlying region type
@@ -354,7 +354,7 @@
     // a pointer.  We may wish to flag a type error here if the types
     // are incompatible.  This may also cause lots of breakage
     // elsewhere. Food for thought.
-    if (TyR->isBoundable() && Loc::IsLocType(TyR->getValueType(C)))              
+    if (TyR->isBoundable() && Loc::IsLocType(TyR->getValueType(C)))
       V = X->getLoc();
   }
 
@@ -368,10 +368,10 @@
   switch (loc.getSubKind()) {
     case loc::MemRegionKind: {
       const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
-      
+
       if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
         return store;
-      
+
       return VBFactory.Remove(GetBindings(store), R).getRoot();
     }
     default:
@@ -384,11 +384,11 @@
 BasicStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc,
                                       SymbolReaper& SymReaper,
                            llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
-{  
+{
   Store store = state.getStore();
   BindingsTy B = GetBindings(store);
   typedef SVal::symbol_iterator symbol_iterator;
-  
+
   // Iterate over the variable bindings.
   for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
     if (const VarRegion *VR = dyn_cast<VarRegion>(I.getKey())) {
@@ -402,20 +402,20 @@
     }
     else
       continue;
-    
+
     // Mark the bindings in the data as live.
     SVal X = I.getData();
     for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
       SymReaper.markLive(*SI);
   }
-  
+
   // Scan for live variables and live symbols.
   llvm::SmallPtrSet<const MemRegion*, 10> Marked;
-  
+
   while (!RegionRoots.empty()) {
     const MemRegion* MR = RegionRoots.back();
     RegionRoots.pop_back();
-    
+
     while (MR) {
       if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(MR)) {
         SymReaper.markLive(SymR->getSymbol());
@@ -424,17 +424,17 @@
       else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR)) {
         if (Marked.count(MR))
           break;
-        
-        Marked.insert(MR);        
+
+        Marked.insert(MR);
         SVal X = Retrieve(&state, loc::MemRegionVal(MR)).getSVal();
-    
+
         // FIXME: We need to handle symbols nested in region definitions.
         for (symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
           SymReaper.markLive(*SI);
-    
+
         if (!isa<loc::MemRegionVal>(X))
           break;
-    
+
         const loc::MemRegionVal& LVD = cast<loc::MemRegionVal>(X);
         RegionRoots.push_back(LVD.getRegion());
         break;
@@ -445,15 +445,15 @@
         break;
     }
   }
-  
-  // Remove dead variable bindings.  
+
+  // Remove dead variable bindings.
   for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
     const MemRegion* R = I.getKey();
-    
+
     if (!Marked.count(R)) {
       store = Remove(store, ValMgr.makeLoc(R));
       SVal X = I.getData();
-      
+
       for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
         SymReaper.maybeDead(*SI);
     }
@@ -467,10 +467,10 @@
                                       const MemRegion *SelfRegion, Store St) {
   for (Stmt::child_iterator CI=B->child_begin(), CE=B->child_end();
        CI != CE; ++CI) {
-    
+
     if (!*CI)
       continue;
-    
+
     // Check if the statement is an ivar reference.  We only
     // care about self.ivar.
     if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(*CI)) {
@@ -478,8 +478,8 @@
       if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Base)) {
         if (DR->getDecl() == SelfDecl) {
           const MemRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(),
-                                                         SelfRegion);          
-          SVal X = ValMgr.getRegionValueSymbolVal(IVR);          
+                                                         SelfRegion);
+          SVal X = ValMgr.getRegionValueSymbolVal(IVR);
           St = BindInternal(St, ValMgr.makeLoc(IVR), X);
         }
       }
@@ -487,11 +487,11 @@
     else
       St = scanForIvars(*CI, SelfDecl, SelfRegion, St);
   }
-  
+
   return St;
 }
 
-Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {  
+Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
   // The LiveVariables information already has a compilation of all VarDecls
   // used in the function.  Iterate through this set, and "symbolicate"
   // any VarDecl whose value originally comes from outside the function.
@@ -504,7 +504,7 @@
 
     // Handle implicit parameters.
     if (ImplicitParamDecl* PD = dyn_cast<ImplicitParamDecl>(ND)) {
-      const Decl& CD = *InitLoc->getDecl();      
+      const Decl& CD = *InitLoc->getDecl();
       if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CD)) {
         if (MD->getSelfDecl() == PD) {
           // FIXME: Just use a symbolic region, and remove ObjCObjectRegion
@@ -512,10 +512,10 @@
           const ObjCObjectRegion *SelfRegion =
             MRMgr.getObjCObjectRegion(MD->getClassInterface(),
                                       MRMgr.getHeapRegion());
-          
+
           St = BindInternal(St, ValMgr.makeLoc(MRMgr.getVarRegion(PD, InitLoc)),
                             ValMgr.makeLoc(SelfRegion));
-          
+
           // Scan the method for ivar references.  While this requires an
           // entire AST scan, the cost should not be high in practice.
           St = scanForIvars(MD->getBody(), PD, SelfRegion, St);
@@ -543,9 +543,9 @@
 Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
                                           const LocationContext *LC,
                                           SVal* InitVal) {
-                 
+
   BasicValueFactory& BasicVals = StateMgr.getBasicVals();
-                 
+
   // BasicStore does not model arrays and structs.
   if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
     return store;
@@ -560,14 +560,14 @@
     // Static global variables should not be visited here.
     assert(!(VD->getStorageClass() == VarDecl::Static &&
              VD->isFileVarDecl()));
-    
+
     // Process static variables.
     if (VD->getStorageClass() == VarDecl::Static) {
       // C99: 6.7.8 Initialization
       //  If an object that has static storage duration is not initialized
-      //  explicitly, then: 
-      //   —if it has pointer type, it is initialized to a null pointer; 
-      //   —if it has arithmetic type, it is initialized to (positive or 
+      //  explicitly, then:
+      //   —if it has pointer type, it is initialized to a null pointer;
+      //   —if it has arithmetic type, it is initialized to (positive or
       //     unsigned) zero;
       if (!InitVal) {
         QualType T = VD->getType();
@@ -598,18 +598,18 @@
 
 void BasicStoreManager::print(Store store, llvm::raw_ostream& Out,
                               const char* nl, const char *sep) {
-      
+
   BindingsTy B = GetBindings(store);
   Out << "Variables:" << nl;
-  
+
   bool isFirst = true;
-  
+
   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
     if (isFirst)
       isFirst = false;
     else
       Out << nl;
-    
+
     Out << ' ' << I.getKey() << " : " << I.getData();
   }
 }
@@ -617,7 +617,7 @@
 
 void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
   BindingsTy B = GetBindings(store);
-  
+
   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I)
     f.HandleBinding(*this, store, I.getKey(), I.getData());
 
@@ -634,10 +634,10 @@
                                                    const Expr *E,
                                                    unsigned Count) {
   R = R->getBaseRegion();
-  
+
   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
       return state;
-      
+
   QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
   SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
   return Bind(state, loc::MemRegionVal(R), V);
