diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 9cd59c2..e511f76 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -22,7 +22,7 @@
 #include "clang/Analysis/PathSensitive/BugReporter.h"
 #include "clang/Analysis/PathSensitive/SymbolManager.h"
 #include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/AST/DeclObjC.h"   
+#include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableMap.h"
@@ -44,7 +44,7 @@
 //     MemoryMgmt/Tasks/MemoryManagementRules.html
 //
 // "You take ownership of an object if you create it using a method whose name
-//  begins with "alloc" or "new" or contains "copy" (for example, alloc, 
+//  begins with "alloc" or "new" or contains "copy" (for example, alloc,
 //  newObject, or mutableCopy), or if you send it a retain message. You are
 //  responsible for relinquishing ownership of objects you own using release
 //  or autorelease. Any other time you receive an object, you must
@@ -62,8 +62,8 @@
       || (isupper(prev) && isupper(ch) && islower(next)) // XXCreate
       || !isalpha(ch);
 }
-  
-static inline const char* parseWord(const char* s) {  
+
+static inline const char* parseWord(const char* s) {
   char ch = *s, prev = '\0';
   assert(ch != '\0');
   char next = *(s+1);
@@ -77,18 +77,18 @@
 
 static NamingConvention deriveNamingConvention(Selector S) {
   IdentifierInfo *II = S.getIdentifierInfoForSlot(0);
-  
+
   if (!II)
     return NoConvention;
-  
+
   const char *s = II->getName();
-  
+
   // A method/function name may contain a prefix.  We don't know it is there,
   // however, until we encounter the first '_'.
   bool InPossiblePrefix = true;
   bool AtBeginning = true;
   NamingConvention C = NoConvention;
-  
+
   while (*s != '\0') {
     // Skip '_'.
     if (*s == '_') {
@@ -103,24 +103,24 @@
       ++s;
       continue;
     }
-    
+
     // Skip numbers, ':', etc.
     if (!isalpha(*s)) {
       ++s;
       continue;
     }
-    
+
     const char *wordEnd = parseWord(s);
     assert(wordEnd > s);
     unsigned len = wordEnd - s;
-    
+
     switch (len) {
     default:
       break;
     case 3:
       // Methods starting with 'new' follow the create rule.
       if (AtBeginning && StringsEqualNoCase("new", s, len))
-        C = CreateRule;      
+        C = CreateRule;
       break;
     case 4:
       // Methods starting with 'alloc' or contain 'copy' follow the
@@ -136,7 +136,7 @@
         C = CreateRule;
       break;
     }
-    
+
     // If we aren't in the prefix and have a derived convention then just
     // return it now.
     if (!InPossiblePrefix && C != NoConvention)
@@ -156,10 +156,10 @@
 }
 
 static const ObjCMethodDecl*
-ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {  
+ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
   ObjCInterfaceDecl *ID =
     const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());
-  
+
   return MD->isInstanceMethod()
          ? ID->lookupInstanceMethod(MD->getSelector())
          : ID->lookupClassMethod(MD->getSelector());
@@ -178,12 +178,12 @@
 
   GenericNodeBuilder(GREndPathNodeBuilder &enb)
   : SNB(0), S(0), tag(0), ENB(&enb) {}
-  
+
   ExplodedNode *MakeNode(const GRState *state, ExplodedNode *Pred) {
     if (SNB)
-      return SNB->generateNode(PostStmt(S, Pred->getLocationContext(), tag), 
+      return SNB->generateNode(PostStmt(S, Pred->getLocationContext(), tag),
                                state, Pred);
-    
+
     assert(ENB);
     return ENB->generateNode(state, Pred);
   }
@@ -211,16 +211,16 @@
 static bool hasPrefix(const char* s, const char* prefix) {
   if (!prefix)
     return true;
-  
+
   char c = *s;
   char cP = *prefix;
-  
+
   while (c != '\0' && cP != '\0') {
     if (c != cP) break;
     c = *(++s);
     cP = *(++prefix);
   }
-  
+
   return cP == '\0';
 }
 
@@ -231,14 +231,14 @@
 
 static bool isRefType(QualType RetTy, const char* prefix,
                       ASTContext* Ctx = 0, const char* name = 0) {
-  
+
   // Recursively walk the typedef stack, allowing typedefs of reference types.
   while (1) {
     if (TypedefType* TD = dyn_cast<TypedefType>(RetTy.getTypePtr())) {
       const char* TDName = TD->getDecl()->getIdentifier()->getName();
       if (hasPrefix(TDName, prefix) && hasSuffix(TDName, "Ref"))
         return true;
-      
+
       RetTy = TD->getDecl()->getUnderlyingType();
       continue;
     }
@@ -282,14 +282,14 @@
 namespace {
 
 ///  RetEffect is used to summarize a function/method call's behavior with
-///  respect to its return value.  
+///  respect to its return value.
 class VISIBILITY_HIDDEN RetEffect {
 public:
   enum Kind { NoRet, Alias, OwnedSymbol, OwnedAllocatedSymbol,
               NotOwnedSymbol, GCNotOwnedSymbol, ReceiverAlias,
               OwnedWhenTrackedReceiver };
-    
-  enum ObjKind { CF, ObjC, AnyObj };  
+
+  enum ObjKind { CF, ObjC, AnyObj };
 
 private:
   Kind K;
@@ -298,124 +298,124 @@
 
   RetEffect(Kind k, unsigned idx = 0) : K(k), O(AnyObj), index(idx) {}
   RetEffect(Kind k, ObjKind o) : K(k), O(o), index(0) {}
-  
+
 public:
   Kind getKind() const { return K; }
 
   ObjKind getObjKind() const { return O; }
-  
-  unsigned getIndex() const { 
+
+  unsigned getIndex() const {
     assert(getKind() == Alias);
     return index;
   }
-  
+
   bool isOwned() const {
     return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
            K == OwnedWhenTrackedReceiver;
   }
-    
+
   static RetEffect MakeOwnedWhenTrackedReceiver() {
     return RetEffect(OwnedWhenTrackedReceiver, ObjC);
   }
-  
+
   static RetEffect MakeAlias(unsigned Idx) {
     return RetEffect(Alias, Idx);
   }
   static RetEffect MakeReceiverAlias() {
     return RetEffect(ReceiverAlias);
-  }  
+  }
   static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
     return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
-  }  
+  }
   static RetEffect MakeNotOwned(ObjKind o) {
     return RetEffect(NotOwnedSymbol, o);
   }
   static RetEffect MakeGCNotOwned() {
     return RetEffect(GCNotOwnedSymbol, ObjC);
   }
-    
+
   static RetEffect MakeNoRet() {
     return RetEffect(NoRet);
   }
-  
+
   void Profile(llvm::FoldingSetNodeID& ID) const {
     ID.AddInteger((unsigned)K);
     ID.AddInteger((unsigned)O);
     ID.AddInteger(index);
   }
 };
-  
-  
+
+
 class VISIBILITY_HIDDEN RetainSummary {
   /// Args - an ordered vector of (index, ArgEffect) pairs, where index
   ///  specifies the argument (starting from 0).  This can be sparsely
   ///  populated; arguments with no entry in Args use 'DefaultArgEffect'.
   ArgEffects Args;
-  
+
   /// DefaultArgEffect - The default ArgEffect to apply to arguments that
   ///  do not have an entry in Args.
   ArgEffect   DefaultArgEffect;
-  
+
   /// Receiver - If this summary applies to an Objective-C message expression,
   ///  this is the effect applied to the state of the receiver.
   ArgEffect   Receiver;
-  
+
   /// Ret - The effect on the return value.  Used to indicate if the
   ///  function/method call returns a new tracked symbol, returns an
   ///  alias of one of the arguments in the call, and so on.
   RetEffect   Ret;
-  
+
   /// EndPath - Indicates that execution of this method/function should
   ///  terminate the simulation of a path.
   bool EndPath;
-  
+
 public:
   RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,
                 ArgEffect ReceiverEff, bool endpath = false)
     : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R),
-      EndPath(endpath) {}  
-  
+      EndPath(endpath) {}
+
   /// getArg - Return the argument effect on the argument specified by
   ///  idx (starting from 0).
   ArgEffect getArg(unsigned idx) const {
     if (const ArgEffect *AE = Args.lookup(idx))
       return *AE;
-    
+
     return DefaultArgEffect;
   }
-  
+
   /// setDefaultArgEffect - Set the default argument effect.
   void setDefaultArgEffect(ArgEffect E) {
     DefaultArgEffect = E;
   }
-  
+
   /// setArg - Set the argument effect on the argument specified by idx.
   void setArgEffect(ArgEffects::Factory& AF, unsigned idx, ArgEffect E) {
     Args = AF.Add(Args, idx, E);
   }
-  
+
   /// getRetEffect - Returns the effect on the return value of the call.
   RetEffect getRetEffect() const { return Ret; }
-  
+
   /// setRetEffect - Set the effect of the return value of the call.
   void setRetEffect(RetEffect E) { Ret = E; }
-  
+
   /// isEndPath - Returns true if executing the given method/function should
   ///  terminate the path.
   bool isEndPath() const { return EndPath; }
-  
+
   /// getReceiverEffect - Returns the effect on the receiver of the call.
   ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
   ArgEffect getReceiverEffect() const { return Receiver; }
-  
+
   /// setReceiverEffect - Set the effect on the receiver of the call.
   void setReceiverEffect(ArgEffect E) { Receiver = E; }
-  
+
   typedef ArgEffects::iterator ExprIterator;
-  
+
   ExprIterator begin_args() const { return Args.begin(); }
   ExprIterator end_args()   const { return Args.end(); }
-  
+
   static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects A,
                       RetEffect RetEff, ArgEffect DefaultEff,
                       ArgEffect ReceiverEff, bool EndPath) {
@@ -425,7 +425,7 @@
     ID.AddInteger((unsigned) ReceiverEff);
     ID.AddInteger((unsigned) EndPath);
   }
-      
+
   void Profile(llvm::FoldingSetNodeID& ID) const {
     Profile(ID, Args, Ret, DefaultArgEffect, Receiver, EndPath);
   }
@@ -440,7 +440,7 @@
 class VISIBILITY_HIDDEN ObjCSummaryKey {
   IdentifierInfo* II;
   Selector S;
-public:    
+public:
   ObjCSummaryKey(IdentifierInfo* ii, Selector s)
     : II(ii), S(s) {}
 
@@ -449,10 +449,10 @@
 
   ObjCSummaryKey(const ObjCInterfaceDecl* d, IdentifierInfo *ii, Selector s)
     : II(d ? d->getIdentifier() : ii), S(s) {}
-  
+
   ObjCSummaryKey(Selector s)
     : II(0), S(s) {}
-  
+
   IdentifierInfo* getIdentifier() const { return II; }
   Selector getSelector() const { return S; }
 };
@@ -464,56 +464,56 @@
     return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
                           DenseMapInfo<Selector>::getEmptyKey());
   }
-    
+
   static inline ObjCSummaryKey getTombstoneKey() {
     return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
-                          DenseMapInfo<Selector>::getTombstoneKey());      
+                          DenseMapInfo<Selector>::getTombstoneKey());
   }
-  
+
   static unsigned getHashValue(const ObjCSummaryKey &V) {
     return (DenseMapInfo<IdentifierInfo*>::getHashValue(V.getIdentifier())
-            & 0x88888888) 
+            & 0x88888888)
         | (DenseMapInfo<Selector>::getHashValue(V.getSelector())
             & 0x55555555);
   }
-  
+
   static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
     return DenseMapInfo<IdentifierInfo*>::isEqual(LHS.getIdentifier(),
                                                   RHS.getIdentifier()) &&
            DenseMapInfo<Selector>::isEqual(LHS.getSelector(),
                                            RHS.getSelector());
   }
-  
+
   static bool isPod() {
     return DenseMapInfo<ObjCInterfaceDecl*>::isPod() &&
            DenseMapInfo<Selector>::isPod();
   }
 };
 } // end llvm namespace
-  
+
 namespace {
 class VISIBILITY_HIDDEN ObjCSummaryCache {
   typedef llvm::DenseMap<ObjCSummaryKey, RetainSummary*> MapTy;
   MapTy M;
 public:
   ObjCSummaryCache() {}
-    
+
   RetainSummary* find(const ObjCInterfaceDecl* D, IdentifierInfo *ClsName,
                 Selector S) {
     // Lookup the method using the decl for the class @interface.  If we
     // have no decl, lookup using the class name.
     return D ? find(D, S) : find(ClsName, S);
   }
-  
-  RetainSummary* find(const ObjCInterfaceDecl* D, Selector S) {    
+
+  RetainSummary* find(const ObjCInterfaceDecl* D, Selector S) {
     // Do a lookup with the (D,S) pair.  If we find a match return
     // the iterator.
     ObjCSummaryKey K(D, S);
     MapTy::iterator I = M.find(K);
-    
+
     if (I != M.end() || !D)
       return I->second;
-    
+
     // Walk the super chain.  If we find a hit with a parent, we'll end
     // up returning that summary.  We actually allow that key (null,S), as
     // we cache summaries for the null ObjCInterfaceDecl* to allow us to
@@ -523,62 +523,62 @@
     for (ObjCInterfaceDecl* C=D->getSuperClass() ;; C=C->getSuperClass()) {
       if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
         break;
-      
+
       if (!C)
         return NULL;
     }
-    
-    // Cache the summary with original key to make the next lookup faster 
+
+    // Cache the summary with original key to make the next lookup faster
     // and return the iterator.
     RetainSummary *Summ = I->second;
     M[K] = Summ;
     return Summ;
   }
-  
+
 
   RetainSummary* find(Expr* Receiver, Selector S) {
     return find(getReceiverDecl(Receiver), S);
   }
-  
+
   RetainSummary* find(IdentifierInfo* II, Selector S) {
     // FIXME: Class method lookup.  Right now we dont' have a good way
     // of going between IdentifierInfo* and the class hierarchy.
     MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
-    
+
     if (I == M.end())
       I = M.find(ObjCSummaryKey(S));
-      
+
     return I == M.end() ? NULL : I->second;
   }
-  
-  const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {    
+
+  const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
     if (const ObjCObjectPointerType* PT =
         E->getType()->getAsObjCObjectPointerType())
       return PT->getInterfaceDecl();
 
     return NULL;
   }
-  
+
   RetainSummary*& operator[](ObjCMessageExpr* ME) {
-    
+
     Selector S = ME->getSelector();
-    
+
     if (Expr* Receiver = ME->getReceiver()) {
       const ObjCInterfaceDecl* OD = getReceiverDecl(Receiver);
       return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
     }
-    
+
     return M[ObjCSummaryKey(ME->getClassName(), S)];
   }
-  
+
   RetainSummary*& operator[](ObjCSummaryKey K) {
     return M[K];
   }
-  
+
   RetainSummary*& operator[](Selector S) {
     return M[ ObjCSummaryKey(S) ];
   }
-};   
+};
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
@@ -591,29 +591,29 @@
   //==-----------------------------------------------------------------==//
   //  Typedefs.
   //==-----------------------------------------------------------------==//
-  
+
   typedef llvm::DenseMap<FunctionDecl*, RetainSummary*>
           FuncSummariesTy;
-  
+
   typedef ObjCSummaryCache ObjCMethodSummariesTy;
-    
+
   //==-----------------------------------------------------------------==//
   //  Data.
   //==-----------------------------------------------------------------==//
-  
+
   /// Ctx - The ASTContext object for the analyzed ASTs.
   ASTContext& Ctx;
 
   /// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
   ///  "CFDictionaryCreate".
   IdentifierInfo* CFDictionaryCreateII;
-  
+
   /// GCEnabled - Records whether or not the analyzed code runs in GC mode.
   const bool GCEnabled;
-    
+
   /// FuncSummaries - A map from FunctionDecls to summaries.
-  FuncSummariesTy FuncSummaries; 
-  
+  FuncSummariesTy FuncSummaries;
+
   /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
   ///  to summaries.
   ObjCMethodSummariesTy ObjCClassMethodSummaries;
@@ -624,34 +624,34 @@
   /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
   ///  and all other data used by the checker.
   llvm::BumpPtrAllocator BPAlloc;
-  
+
   /// AF - A factory for ArgEffects objects.
-  ArgEffects::Factory AF;  
-  
+  ArgEffects::Factory AF;
+
   /// ScratchArgs - A holding buffer for construct ArgEffects.
   ArgEffects ScratchArgs;
-  
+
   /// ObjCAllocRetE - Default return effect for methods returning Objective-C
   ///  objects.
   RetEffect ObjCAllocRetE;
 
-  /// ObjCInitRetE - Default return effect for init methods returning 
+  /// ObjCInitRetE - Default return effect for init methods returning
   ///   Objective-C objects.
   RetEffect ObjCInitRetE;
-  
+
   RetainSummary DefaultSummary;
   RetainSummary* StopSummary;
-  
+
   //==-----------------------------------------------------------------==//
   //  Methods.
   //==-----------------------------------------------------------------==//
-  
+
   /// getArgEffects - Returns a persistent ArgEffects object based on the
   ///  data in ScratchArgs.
   ArgEffects getArgEffects();
 
-  enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };  
-  
+  enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };
+
 public:
   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
 
@@ -659,13 +659,13 @@
     RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
     return new (Summ) RetainSummary(DefaultSummary);
   }
-  
+
   RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
-  
+
   RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
-  RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);  
+  RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
   RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, const char* FName);
-  
+
   RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
                                       ArgEffect ReceiverEff = DoNothing,
                                       ArgEffect DefaultEff = MayEscape,
@@ -676,36 +676,36 @@
                                       ArgEffect DefaultEff = MayEscape) {
     return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
   }
-  
+
   RetainSummary *getPersistentStopSummary() {
     if (StopSummary)
       return StopSummary;
-    
+
     StopSummary = getPersistentSummary(RetEffect::MakeNoRet(),
                                        StopTracking, StopTracking);
 
     return StopSummary;
-  }  
+  }
 
   RetainSummary *getInitMethodSummary(QualType RetTy);
 
   void InitializeClassMethodSummaries();
   void InitializeMethodSummaries();
-  
+
   bool isTrackedObjCObjectType(QualType T);
   bool isTrackedCFObjectType(QualType T);
-  
+
 private:
-  
+
   void addClsMethSummary(IdentifierInfo* ClsII, Selector S,
                          RetainSummary* Summ) {
     ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
   }
-  
+
   void addNSObjectClsMethSummary(Selector S, RetainSummary *Summ) {
     ObjCClassMethodSummaries[S] = Summ;
   }
-    
+
   void addNSObjectMethSummary(Selector S, RetainSummary *Summ) {
     ObjCMethodSummaries[S] = Summ;
   }
@@ -716,43 +716,43 @@
     Selector S = GetNullarySelector(nullaryName, Ctx);
     ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
   }
-  
+
   void addInstMethSummary(const char* Cls, const char* nullaryName,
                           RetainSummary *Summ) {
     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
     Selector S = GetNullarySelector(nullaryName, Ctx);
     ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
   }
-  
+
   Selector generateSelector(va_list argp) {
     llvm::SmallVector<IdentifierInfo*, 10> II;
 
     while (const char* s = va_arg(argp, const char*))
       II.push_back(&Ctx.Idents.get(s));
 
-    return Ctx.Selectors.getSelector(II.size(), &II[0]);    
+    return Ctx.Selectors.getSelector(II.size(), &II[0]);
   }
-  
+
   void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy& Summaries,
                         RetainSummary* Summ, va_list argp) {
     Selector S = generateSelector(argp);
     Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
   }
-  
+
   void addInstMethSummary(const char* Cls, RetainSummary* Summ, ...) {
     va_list argp;
     va_start(argp, Summ);
     addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
-    va_end(argp);    
+    va_end(argp);
   }
-  
+
   void addClsMethSummary(const char* Cls, RetainSummary* Summ, ...) {
     va_list argp;
     va_start(argp, Summ);
     addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp);
     va_end(argp);
   }
-  
+
   void addClsMethSummary(IdentifierInfo *II, RetainSummary* Summ, ...) {
     va_list argp;
     va_start(argp, Summ);
@@ -769,9 +769,9 @@
     addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
     va_end(argp);
   }
-  
+
 public:
-  
+
   RetainSummaryManager(ASTContext& ctx, bool gcenabled)
    : Ctx(ctx),
      CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
@@ -789,17 +789,17 @@
     InitializeClassMethodSummaries();
     InitializeMethodSummaries();
   }
-  
+
   ~RetainSummaryManager();
-  
-  RetainSummary* getSummary(FunctionDecl* FD);  
-  
+
+  RetainSummary* getSummary(FunctionDecl* FD);
+
   RetainSummary* getInstanceMethodSummary(ObjCMessageExpr* ME,
                                           const ObjCInterfaceDecl* ID) {
     return getInstanceMethodSummary(ME->getSelector(), ME->getClassName(),
-                            ID, ME->getMethodDecl(), ME->getType());    
+                            ID, ME->getMethodDecl(), ME->getType());
   }
-  
+
   RetainSummary* getInstanceMethodSummary(Selector S, IdentifierInfo *ClsName,
                                           const ObjCInterfaceDecl* ID,
                                           const ObjCMethodDecl *MD,
@@ -809,7 +809,7 @@
                                        const ObjCInterfaceDecl *ID,
                                        const ObjCMethodDecl *MD,
                                        QualType RetTy);
-  
+
   RetainSummary *getClassMethodSummary(ObjCMessageExpr *ME) {
     return getClassMethodSummary(ME->getSelector(), ME->getClassName(),
                                  ME->getClassInfo().first,
@@ -824,17 +824,17 @@
     Selector S = MD->getSelector();
     IdentifierInfo *ClsName = ID->getIdentifier();
     QualType ResultTy = MD->getResultType();
-    
-    // Resolve the method decl last.    
+
+    // Resolve the method decl last.
     if (const ObjCMethodDecl *InterfaceMD = ResolveToInterfaceMethodDecl(MD))
       MD = InterfaceMD;
-    
+
     if (MD->isInstanceMethod())
       return getInstanceMethodSummary(S, ClsName, ID, MD, ResultTy);
     else
       return getClassMethodSummary(S, ClsName, ID, MD, ResultTy);
   }
-  
+
   RetainSummary* getCommonMethodSummary(const ObjCMethodDecl* MD,
                                         Selector S, QualType RetTy);
 
@@ -845,14 +845,14 @@
                                     const FunctionDecl *FD);
 
   bool isGCEnabled() const { return GCEnabled; }
-  
+
   RetainSummary *copySummary(RetainSummary *OldSumm) {
     RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
     new (Summ) RetainSummary(*OldSumm);
     return Summ;
-  }  
+  }
 };
-  
+
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
@@ -871,7 +871,7 @@
 RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff,
                                            ArgEffect ReceiverEff,
                                            ArgEffect DefaultEff,
-                                           bool isEndPath) {  
+                                           bool isEndPath) {
   // Create the summary and return it.
   RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
   new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff, isEndPath);
@@ -887,31 +887,31 @@
     return false;
 
   const ObjCObjectPointerType *PT = Ty->getAsObjCObjectPointerType();
-  
+
   // Can be true for objects with the 'NSObject' attribute.
   if (!PT)
     return true;
-  
+
   // We assume that id<..>, id, and "Class" all represent tracked objects.
   if (PT->isObjCIdType() || PT->isObjCQualifiedIdType() ||
       PT->isObjCClassType())
     return true;
 
-  // Does the interface subclass NSObject?    
-  // FIXME: We can memoize here if this gets too expensive.    
-  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();  
+  // Does the interface subclass NSObject?
+  // FIXME: We can memoize here if this gets too expensive.
+  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
 
   // Assume that anything declared with a forward declaration and no
   // @interface subclasses NSObject.
   if (ID->isForwardDecl())
     return true;
-  
+
   IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
 
   for ( ; ID ; ID = ID->getSuperClass())
     if (ID->getIdentifier() == NSObjectII)
       return true;
-  
+
   return false;
 }
 
@@ -945,33 +945,33 @@
 
   // No summary?  Generate one.
   RetainSummary *S = 0;
-  
+
   do {
     // We generate "stop" summaries for implicitly defined functions.
     if (FD->isImplicit()) {
       S = getPersistentStopSummary();
       break;
     }
-    
+
     // [PR 3337] Use 'getAsFunctionType' to strip away any typedefs on the
     // function's type.
     const FunctionType* FT = FD->getType()->getAsFunctionType();
     const char* FName = FD->getIdentifier()->getName();
-    
+
     // Strip away preceding '_'.  Doing this here will effect all the checks
     // down below.
     while (*FName == '_') ++FName;
-    
+
     // Inspect the result type.
     QualType RetTy = FT->getResultType();
-    
+
     // FIXME: This should all be refactored into a chain of "summary lookup"
     //  filters.
     assert (ScratchArgs.isEmpty());
-    
+
     switch (strlen(FName)) {
       default: break;
-        
+
 
       case 17:
         // Handle: id NSMakeCollectable(CFTypeRef)
@@ -1003,10 +1003,10 @@
           // Part of <rdar://problem/6961230>. (IOKit)
           // This should be addressed using a API table.
           ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
-          S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);         
+          S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
         }
         break;
-        
+
       case 25:
         if (!memcmp(FName, "IORegistryEntryIDMatching", 25)) {
           // Part of <rdar://problem/6961230>. (IOKit)
@@ -1015,13 +1015,13 @@
                                    DoNothing, DoNothing);
         }
         break;
-        
+
       case 26:
         if (!memcmp(FName, "IOOpenFirmwarePathMatching", 26)) {
           // Part of <rdar://problem/6961230>. (IOKit)
           // This should be addressed using a API table.
           S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
-                                   DoNothing, DoNothing);          
+                                   DoNothing, DoNothing);
         }
         break;
 
@@ -1030,7 +1030,7 @@
           // Part of <rdar://problem/6961230>.
           // This should be addressed using a API table.
           ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
-          S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);         
+          S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
         }
         break;
 
@@ -1043,17 +1043,17 @@
           S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
         }
         break;
-        
+
       case 32:
         if (!memcmp(FName, "IOServiceAddMatchingNotification", 32)) {
           // Part of <rdar://problem/6961230>.
           // This should be addressed using a API table.
           ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
-          S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);         
+          S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
         }
         break;
     }
-    
+
     // Did we get a summary?
     if (S)
       break;
@@ -1063,7 +1063,7 @@
 #if 0
     // Handle: NSDeallocateObject(id anObject);
     // This method does allow 'nil' (although we don't check it now).
-    if (strcmp(FName, "NSDeallocateObject") == 0) {      
+    if (strcmp(FName, "NSDeallocateObject") == 0) {
       return RetTy == Ctx.VoidTy
         ? getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, Dealloc)
         : getPersistentStopSummary();
@@ -1077,7 +1077,7 @@
           S = getUnarySummary(FT, cfretain);
         else if (strstr(FName, "MakeCollectable"))
           S = getUnarySummary(FT, cfmakecollectable);
-        else 
+        else
           S = getCFCreateGetRuleSummary(FD, FName);
 
         break;
@@ -1100,7 +1100,7 @@
         S = getCFCreateGetRuleSummary(FD, FName);
         break;
       }
-      
+
       break;
     }
 
@@ -1112,7 +1112,7 @@
         FName += 4;
       else
         FName += 2;
-      
+
       if (isRelease(FD, FName))
         S = getUnarySummary(FT, cfrelease);
       else {
@@ -1122,9 +1122,9 @@
         // and that ownership cannot be transferred.  While this is technically
         // correct, many methods allow a tracked object to escape.  For example:
         //
-        //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);        
+        //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);
         //   CFDictionaryAddValue(y, key, x);
-        //   CFRelease(x); 
+        //   CFRelease(x);
         //   ... it is okay to use 'x' since 'y' has a reference to it
         //
         // We handle this and similar cases with the follow heuristic.  If the
@@ -1138,34 +1138,34 @@
                        CStrInCStrNoCase(FName, "AppendValue") ||
                        CStrInCStrNoCase(FName, "SetAttribute"))
                       ? MayEscape : DoNothing;
-        
+
         S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);
       }
     }
   }
   while (0);
-  
+
   if (!S)
     S = getDefaultSummary();
 
   // Annotations override defaults.
   assert(S);
   updateSummaryFromAnnotations(*S, FD);
-  
+
   FuncSummaries[FD] = S;
-  return S;  
+  return S;
 }
 
 RetainSummary*
 RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
                                                 const char* FName) {
-  
+
   if (strstr(FName, "Create") || strstr(FName, "Copy"))
     return getCFSummaryCreateRule(FD);
-  
+
   if (strstr(FName, "Get"))
     return getCFSummaryGetRule(FD);
-  
+
   return getDefaultSummary();
 }
 
@@ -1178,27 +1178,27 @@
   const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
   if (!FTP || FTP->getNumArgs() != 1)
     return getPersistentStopSummary();
-  
+
   assert (ScratchArgs.isEmpty());
-  
+
   switch (func) {
     case cfretain: {
       ScratchArgs = AF.Add(ScratchArgs, 0, IncRef);
       return getPersistentSummary(RetEffect::MakeAlias(0),
                                   DoNothing, DoNothing);
     }
-      
+
     case cfrelease: {
       ScratchArgs = AF.Add(ScratchArgs, 0, DecRef);
       return getPersistentSummary(RetEffect::MakeNoRet(),
                                   DoNothing, DoNothing);
     }
-      
+
     case cfmakecollectable: {
       ScratchArgs = AF.Add(ScratchArgs, 0, MakeCollectable);
-      return getPersistentSummary(RetEffect::MakeAlias(0),DoNothing, DoNothing);    
+      return getPersistentSummary(RetEffect::MakeAlias(0),DoNothing, DoNothing);
     }
-      
+
     default:
       assert (false && "Not a supported unary function.");
       return getDefaultSummary();
@@ -1207,17 +1207,17 @@
 
 RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
   assert (ScratchArgs.isEmpty());
-  
+
   if (FD->getIdentifier() == CFDictionaryCreateII) {
     ScratchArgs = AF.Add(ScratchArgs, 1, DoNothingByRef);
     ScratchArgs = AF.Add(ScratchArgs, 2, DoNothingByRef);
   }
-  
+
   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
 }
 
 RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
-  assert (ScratchArgs.isEmpty());  
+  assert (ScratchArgs.isEmpty());
   return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
                               DoNothing, DoNothing);
 }
@@ -1228,12 +1228,12 @@
 
 RetainSummary*
 RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
-  assert(ScratchArgs.isEmpty());    
+  assert(ScratchArgs.isEmpty());
   // 'init' methods conceptually return a newly allocated object and claim
-  // the receiver.  
+  // the receiver.
   if (isTrackedObjCObjectType(RetTy) || isTrackedCFObjectType(RetTy))
     return getPersistentSummary(ObjCInitRetE, DecRefMsg);
-  
+
   return getDefaultSummary();
 }
 
@@ -1244,7 +1244,7 @@
     return;
 
   QualType RetTy = FD->getResultType();
-  
+
   // Determine if there is a special return effect for this method.
   if (isTrackedObjCObjectType(RetTy)) {
     if (FD->getAttr<NSReturnsRetainedAttr>()) {
@@ -1268,20 +1268,20 @@
     return;
 
   bool isTrackedLoc = false;
-  
+
   // Determine if there is a special return effect for this method.
   if (isTrackedObjCObjectType(MD->getResultType())) {
     if (MD->getAttr<NSReturnsRetainedAttr>()) {
       Summ.setRetEffect(ObjCAllocRetE);
       return;
     }
-    
+
     isTrackedLoc = true;
   }
-  
+
   if (!isTrackedLoc)
     isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL;
-    
+
   if (isTrackedLoc && MD->getAttr<CFReturnsRetainedAttr>())
     Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
 }
@@ -1304,10 +1304,10 @@
           ScratchArgs = AF.Add(ScratchArgs, i, StopTracking);
       }
   }
-  
+
   // Any special effect for the receiver?
   ArgEffect ReceiverEff = DoNothing;
-  
+
   // If one of the arguments in the selector has the keyword 'delegate' we
   // should stop tracking the reference count for the receiver.  This is
   // because the reference count is quite possibly handled by a delegate
@@ -1317,29 +1317,29 @@
     assert(!str.empty());
     if (CStrInCStrNoCase(&str[0], "delegate:")) ReceiverEff = StopTracking;
   }
-  
+
   // Look for methods that return an owned object.
-  if (isTrackedObjCObjectType(RetTy)) {    
+  if (isTrackedObjCObjectType(RetTy)) {
     // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
     //  by instance methods.
     RetEffect E = followsFundamentalRule(S)
                   ? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC);
-    
-    return getPersistentSummary(E, ReceiverEff, MayEscape);    
+
+    return getPersistentSummary(E, ReceiverEff, MayEscape);
   }
-  
+
   // Look for methods that return an owned core foundation object.
   if (isTrackedCFObjectType(RetTy)) {
     RetEffect E = followsFundamentalRule(S)
       ? RetEffect::MakeOwned(RetEffect::CF, true)
       : RetEffect::MakeNotOwned(RetEffect::CF);
-    
+
     return getPersistentSummary(E, ReceiverEff, MayEscape);
   }
-  
+
   if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
     return getDefaultSummary();
-  
+
   return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff, MayEscape);
 }
 
@@ -1352,23 +1352,23 @@
 
   // Look up a summary in our summary cache.
   RetainSummary *Summ = ObjCMethodSummaries.find(ID, ClsName, S);
-  
+
   if (!Summ) {
     assert(ScratchArgs.isEmpty());
-  
+
     // "initXXX": pass-through for receiver.
     if (deriveNamingConvention(S) == InitRule)
       Summ = getInitMethodSummary(RetTy);
     else
       Summ = getCommonMethodSummary(MD, S, RetTy);
-  
+
     // Annotations override defaults.
     updateSummaryFromAnnotations(*Summ, MD);
-  
+
     // Memoize the summary.
     ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
   }
-  
+
   return Summ;
 }
 
@@ -1379,8 +1379,8 @@
                                             QualType RetTy) {
 
   assert(ClsName && "Class name must be specified.");
-  RetainSummary *Summ = ObjCClassMethodSummaries.find(ID, ClsName, S);  
-  
+  RetainSummary *Summ = ObjCClassMethodSummaries.find(ID, ClsName, S);
+
   if (!Summ) {
     Summ = getCommonMethodSummary(MD, S, RetTy);
     // Annotations override defaults.
@@ -1388,32 +1388,32 @@
     // Memoize the summary.
     ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
   }
-  
+
   return Summ;
 }
 
-void RetainSummaryManager::InitializeClassMethodSummaries() {  
+void RetainSummaryManager::InitializeClassMethodSummaries() {
   assert(ScratchArgs.isEmpty());
   RetainSummary* Summ = getPersistentSummary(ObjCAllocRetE);
-  
+
   // Create the summaries for "alloc", "new", and "allocWithZone:" for
   // NSObject and its derivatives.
   addNSObjectClsMethSummary(GetNullarySelector("alloc", Ctx), Summ);
   addNSObjectClsMethSummary(GetNullarySelector("new", Ctx), Summ);
   addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
-  
-  // Create the [NSAssertionHandler currentHander] summary.  
+
+  // Create the [NSAssertionHandler currentHander] summary.
   addClsMethSummary(&Ctx.Idents.get("NSAssertionHandler"),
                 GetNullarySelector("currentHandler", Ctx),
                 getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
-  
+
   // Create the [NSAutoreleasePool addObject:] summary.
   ScratchArgs = AF.Add(ScratchArgs, 0, Autorelease);
   addClsMethSummary(&Ctx.Idents.get("NSAutoreleasePool"),
                     GetUnarySelector("addObject", Ctx),
                     getPersistentSummary(RetEffect::MakeNoRet(),
                                          DoNothing, Autorelease));
-  
+
   // Create the summaries for [NSObject performSelector...].  We treat
   // these as 'stop tracking' for the arguments because they are often
   // used for delegates that can release the object.  When we have better
@@ -1435,7 +1435,7 @@
                     "withObject", "waitUntilDone", "modes", NULL);
   addClsMethSummary(NSObjectII, Summ, "performSelectorInBackground",
                     "withObject", NULL);
-  
+
   // Specially handle NSData.
   RetainSummary *dataWithBytesNoCopySumm =
     getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC), DoNothing,
@@ -1447,43 +1447,43 @@
 }
 
 void RetainSummaryManager::InitializeMethodSummaries() {
-  
-  assert (ScratchArgs.isEmpty());  
-  
+
+  assert (ScratchArgs.isEmpty());
+
   // Create the "init" selector.  It just acts as a pass-through for the
   // receiver.
-  RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg);  
+  RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg);
   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
 
   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
   // claims the receiver and returns a retained object.
   addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx),
                          InitSumm);
-  
+
   // The next methods are allocators.
   RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE);
-  RetainSummary *CFAllocSumm = 
+  RetainSummary *CFAllocSumm =
     getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
-  
-  // Create the "copy" selector.  
-  addNSObjectMethSummary(GetNullarySelector("copy", Ctx), AllocSumm);  
+
+  // Create the "copy" selector.
+  addNSObjectMethSummary(GetNullarySelector("copy", Ctx), AllocSumm);
 
   // Create the "mutableCopy" selector.
   addNSObjectMethSummary(GetNullarySelector("mutableCopy", Ctx), AllocSumm);
-  
+
   // Create the "retain" selector.
   RetEffect E = RetEffect::MakeReceiverAlias();
   RetainSummary *Summ = getPersistentSummary(E, IncRefMsg);
   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
-  
+
   // Create the "release" selector.
   Summ = getPersistentSummary(E, DecRefMsg);
   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
-  
+
   // Create the "drain" selector.
   Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
   addNSObjectMethSummary(GetNullarySelector("drain", Ctx), Summ);
-  
+
   // Create the -dealloc summary.
   Summ = getPersistentSummary(RetEffect::MakeNoRet(), Dealloc);
   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
@@ -1491,13 +1491,13 @@
   // Create the "autorelease" selector.
   Summ = getPersistentSummary(E, Autorelease);
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
-  
+
   // Specially handle NSAutoreleasePool.
   addInstMethSummary("NSAutoreleasePool", "init",
                      getPersistentSummary(RetEffect::MakeReceiverAlias(),
                                           NewAutoreleasePool));
-  
-  // For NSWindow, allocated objects are (initially) self-owned.  
+
+  // For NSWindow, allocated objects are (initially) self-owned.
   // FIXME: For now we opt for false negatives with NSWindow, as these objects
   //  self-own themselves.  However, they only do this once they are displayed.
   //  Thus, we need to track an NSWindow's display status.
@@ -1506,42 +1506,42 @@
   RetainSummary *NoTrackYet = getPersistentSummary(RetEffect::MakeNoRet(),
                                                    StopTracking,
                                                    StopTracking);
-  
+
   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
 
 #if 0
   addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
                      "styleMask", "backing", "defer", NULL);
-  
+
   addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
                      "styleMask", "backing", "defer", "screen", NULL);
 #endif
-  
+
   // For NSPanel (which subclasses NSWindow), allocated objects are not
   //  self-owned.
   // FIXME: For now we don't track NSPanels. object for the same reason
   //   as for NSWindow objects.
   addClassMethSummary("NSPanel", "alloc", NoTrackYet);
-  
+
 #if 0
   addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
                      "styleMask", "backing", "defer", NULL);
-  
+
   addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
                      "styleMask", "backing", "defer", "screen", NULL);
 #endif
-  
+
   // Don't track allocated autorelease pools yet, as it is okay to prematurely
   // exit a method.
   addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
 
   // Create NSAssertionHandler summaries.
   addPanicSummary("NSAssertionHandler", "handleFailureInFunction", "file",
-                  "lineNumber", "description", NULL); 
-  
+                  "lineNumber", "description", NULL);
+
   addPanicSummary("NSAssertionHandler", "handleFailureInMethod", "object",
                   "file", "lineNumber", "description", NULL);
-  
+
   // Create summaries QCRenderer/QCView -createSnapShotImageOfType:
   addInstMethSummary("QCRenderer", AllocSumm,
                      "createSnapshotImageOfType", NULL);
@@ -1554,7 +1554,7 @@
   addInstMethSummary("CIContext", CFAllocSumm,
                      "createCGImage", "fromRect", NULL);
   addInstMethSummary("CIContext", CFAllocSumm,
-                     "createCGImage", "fromRect", "format", "colorSpace", NULL);  
+                     "createCGImage", "fromRect", "format", "colorSpace", NULL);
   addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize",
            "info", NULL);
 }
@@ -1564,19 +1564,19 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
-  
+
 class VISIBILITY_HIDDEN RefVal {
-public:  
+public:
   enum Kind {
-    Owned = 0, // Owning reference.    
-    NotOwned,  // Reference is not owned by still valid (not freed).    
+    Owned = 0, // Owning reference.
+    NotOwned,  // Reference is not owned by still valid (not freed).
     Released,  // Object has been released.
     ReturnedOwned, // Returned object passes ownership to caller.
     ReturnedNotOwned, // Return object does not pass ownership to caller.
     ERROR_START,
     ErrorDeallocNotOwned, // -dealloc called on non-owned object.
     ErrorDeallocGC, // Calling -dealloc with GC enabled.
-    ErrorUseAfterRelease, // Object used after released.    
+    ErrorUseAfterRelease, // Object used after released.
     ErrorReleaseNotOwned, // Release of an object that was not owned.
     ERROR_LEAK_START,
     ErrorLeak,  // A memory leak due to excessive reference counts.
@@ -1587,7 +1587,7 @@
     ErrorReturnedNotOwned
   };
 
-private:  
+private:
   Kind kind;
   RetEffect::ObjKind okind;
   unsigned Cnt;
@@ -1600,9 +1600,9 @@
   RefVal(Kind k, unsigned cnt = 0)
     : kind(k), okind(RetEffect::AnyObj), Cnt(cnt), ACnt(0) {}
 
-public:    
+public:
   Kind getKind() const { return kind; }
-  
+
   RetEffect::ObjKind getObjKind() const { return okind; }
 
   unsigned getCount() const { return Cnt; }
@@ -1611,72 +1611,72 @@
   void clearCounts() { Cnt = 0; ACnt = 0; }
   void setCount(unsigned i) { Cnt = i; }
   void setAutoreleaseCount(unsigned i) { ACnt = i; }
-  
+
   QualType getType() const { return T; }
-  
+
   // Useful predicates.
-  
+
   static bool isError(Kind k) { return k >= ERROR_START; }
-  
+
   static bool isLeak(Kind k) { return k >= ERROR_LEAK_START; }
-  
+
   bool isOwned() const {
     return getKind() == Owned;
   }
-  
+
   bool isNotOwned() const {
     return getKind() == NotOwned;
   }
-  
+
   bool isReturnedOwned() const {
     return getKind() == ReturnedOwned;
   }
-  
+
   bool isReturnedNotOwned() const {
     return getKind() == ReturnedNotOwned;
   }
-  
+
   bool isNonLeakError() const {
     Kind k = getKind();
     return isError(k) && !isLeak(k);
   }
-  
+
   static RefVal makeOwned(RetEffect::ObjKind o, QualType t,
                           unsigned Count = 1) {
     return RefVal(Owned, o, Count, 0, t);
   }
-  
+
   static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t,
                              unsigned Count = 0) {
     return RefVal(NotOwned, o, Count, 0, t);
   }
-  
+
   // Comparison, profiling, and pretty-printing.
-  
+
   bool operator==(const RefVal& X) const {
     return kind == X.kind && Cnt == X.Cnt && T == X.T && ACnt == X.ACnt;
   }
-  
+
   RefVal operator-(size_t i) const {
     return RefVal(getKind(), getObjKind(), getCount() - i,
                   getAutoreleaseCount(), getType());
   }
-  
+
   RefVal operator+(size_t i) const {
     return RefVal(getKind(), getObjKind(), getCount() + i,
                   getAutoreleaseCount(), getType());
   }
-  
+
   RefVal operator^(Kind k) const {
     return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(),
                   getType());
   }
-  
+
   RefVal autorelease() const {
     return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1,
                   getType());
   }
-    
+
   void Profile(llvm::FoldingSetNodeID& ID) const {
     ID.AddInteger((unsigned) kind);
     ID.AddInteger(Cnt);
@@ -1686,41 +1686,41 @@
 
   void print(llvm::raw_ostream& Out) const;
 };
-  
+
 void RefVal::print(llvm::raw_ostream& Out) const {
   if (!T.isNull())
     Out << "Tracked Type:" << T.getAsString() << '\n';
-    
+
   switch (getKind()) {
     default: assert(false);
-    case Owned: { 
+    case Owned: {
       Out << "Owned";
       unsigned cnt = getCount();
       if (cnt) Out << " (+ " << cnt << ")";
       break;
     }
-      
+
     case NotOwned: {
       Out << "NotOwned";
       unsigned cnt = getCount();
       if (cnt) Out << " (+ " << cnt << ")";
       break;
     }
-      
-    case ReturnedOwned: { 
+
+    case ReturnedOwned: {
       Out << "ReturnedOwned";
       unsigned cnt = getCount();
       if (cnt) Out << " (+ " << cnt << ")";
       break;
     }
-      
+
     case ReturnedNotOwned: {
       Out << "ReturnedNotOwned";
       unsigned cnt = getCount();
       if (cnt) Out << " (+ " << cnt << ")";
       break;
     }
-            
+
     case Released:
       Out << "Released";
       break;
@@ -1728,19 +1728,19 @@
     case ErrorDeallocGC:
       Out << "-dealloc (GC)";
       break;
-    
+
     case ErrorDeallocNotOwned:
       Out << "-dealloc (not-owned)";
       break;
-      
+
     case ErrorLeak:
       Out << "Leaked";
-      break;            
-      
+      break;
+
     case ErrorLeakReturned:
       Out << "Leaked (Bad naming)";
       break;
-      
+
     case ErrorGCLeakReturned:
       Out << "Leaked (GC-ed at return)";
       break;
@@ -1748,38 +1748,38 @@
     case ErrorUseAfterRelease:
       Out << "Use-After-Release [ERROR]";
       break;
-      
+
     case ErrorReleaseNotOwned:
       Out << "Release of Not-Owned [ERROR]";
       break;
-      
+
     case RefVal::ErrorOverAutorelease:
       Out << "Over autoreleased";
       break;
-      
+
     case RefVal::ErrorReturnedNotOwned:
       Out << "Non-owned object returned instead of owned";
       break;
   }
-  
+
   if (ACnt) {
     Out << " [ARC +" << ACnt << ']';
   }
 }
-  
+
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // RefBindings - State used to track object reference counts.
 //===----------------------------------------------------------------------===//
-  
+
 typedef llvm::ImmutableMap<SymbolRef, RefVal> RefBindings;
 static int RefBIndex = 0;
 
 namespace clang {
   template<>
   struct GRStateTrait<RefBindings> : public GRStatePartialTrait<RefBindings> {
-    static inline void* GDMIndex() { return &RefBIndex; }  
+    static inline void* GDMIndex() { return &RefBIndex; }
   };
 }
 
@@ -1800,12 +1800,12 @@
 namespace clang {
 template<> struct GRStateTrait<AutoreleaseStack>
   : public GRStatePartialTrait<ARStack> {
-  static inline void* GDMIndex() { return &AutoRBIndex; }  
+  static inline void* GDMIndex() { return &AutoRBIndex; }
 };
 
 template<> struct GRStateTrait<AutoreleasePoolContents>
   : public GRStatePartialTrait<ARPoolContents> {
-  static inline void* GDMIndex() { return &AutoRCIndex; }  
+  static inline void* GDMIndex() { return &AutoRCIndex; }
 };
 } // end clang namespace
 
@@ -1820,14 +1820,14 @@
   SymbolRef pool = GetCurrentAutoreleasePool(state);
   const ARCounts *cnts = state->get<AutoreleasePoolContents>(pool);
   ARCounts newCnts(0);
-  
+
   if (cnts) {
     const unsigned *cnt = (*cnts).lookup(sym);
     newCnts = F.Add(*cnts, sym, cnt ? *cnt  + 1 : 1);
   }
   else
     newCnts = F.Add(F.GetEmptyMap(), sym, 1);
-  
+
   return state->set<AutoreleasePoolContents>(pool, newCnts);
 }
 
@@ -1836,7 +1836,7 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
-  
+
 class VISIBILITY_HIDDEN CFRefCount : public GRTransferFuncs {
 public:
   class BindingsPrinter : public GRState::Printer {
@@ -1847,9 +1847,9 @@
 
 private:
   typedef llvm::DenseMap<const ExplodedNode*, const RetainSummary*>
-    SummaryLogTy;  
+    SummaryLogTy;
 
-  RetainSummaryManager Summaries;  
+  RetainSummaryManager Summaries;
   SummaryLogTy SummaryLog;
   const LangOptions&   LOpts;
   ARCounts::Factory    ARCountFactory;
@@ -1860,7 +1860,7 @@
   BugType *overAutorelease;
   BugType *returnNotOwnedForOwned;
   BugReporter *BR;
-  
+
   const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E,
                     RefVal::Kind& hasErr);
 
@@ -1870,40 +1870,40 @@
                            ExplodedNode* Pred,
                            const GRState* St,
                            RefVal::Kind hasErr, SymbolRef Sym);
-  
+
   const GRState * HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
                                llvm::SmallVectorImpl<SymbolRef> &Leaked);
-    
+
   ExplodedNode* ProcessLeaks(const GRState * state,
                                       llvm::SmallVectorImpl<SymbolRef> &Leaked,
                                       GenericNodeBuilder &Builder,
                                       GRExprEngine &Eng,
                                       ExplodedNode *Pred = 0);
-  
-public:  
+
+public:
   CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
     : Summaries(Ctx, gcenabled),
       LOpts(lopts), useAfterRelease(0), releaseNotOwned(0),
       deallocGC(0), deallocNotOwned(0),
       leakWithinFunction(0), leakAtReturn(0), overAutorelease(0),
       returnNotOwnedForOwned(0), BR(0) {}
-  
+
   virtual ~CFRefCount() {}
-  
+
   void RegisterChecks(BugReporter &BR);
- 
+
   virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {
     Printers.push_back(new BindingsPrinter());
   }
-  
+
   bool isGCEnabled() const { return Summaries.isGCEnabled(); }
   const LangOptions& getLangOptions() const { return LOpts; }
-  
+
   const RetainSummary *getSummaryOfNode(const ExplodedNode *N) const {
     SummaryLogTy::const_iterator I = SummaryLog.find(N);
     return I == SummaryLog.end() ? 0 : I->second;
   }
-  
+
   // Calls.
 
   void EvalSummary(ExplodedNodeSet& Dst,
@@ -1914,47 +1914,47 @@
                    const RetainSummary& Summ,
                    ExprIterator arg_beg, ExprIterator arg_end,
                    ExplodedNode* Pred);
-    
+
   virtual void EvalCall(ExplodedNodeSet& Dst,
                         GRExprEngine& Eng,
                         GRStmtNodeBuilder& Builder,
                         CallExpr* CE, SVal L,
-                        ExplodedNode* Pred);  
-  
-  
+                        ExplodedNode* Pred);
+
+
   virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
                                    GRExprEngine& Engine,
                                    GRStmtNodeBuilder& Builder,
                                    ObjCMessageExpr* ME,
                                    ExplodedNode* Pred);
-  
+
   bool EvalObjCMessageExprAux(ExplodedNodeSet& Dst,
                               GRExprEngine& Engine,
                               GRStmtNodeBuilder& Builder,
                               ObjCMessageExpr* ME,
                               ExplodedNode* Pred);
 
-  // Stores.  
+  // Stores.
   virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
 
   // End-of-path.
-  
+
   virtual void EvalEndPath(GRExprEngine& Engine,
                            GREndPathNodeBuilder& Builder);
-  
+
   virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
                                GRExprEngine& Engine,
                                GRStmtNodeBuilder& Builder,
                                ExplodedNode* Pred,
                                Stmt* S, const GRState* state,
                                SymbolReaper& SymReaper);
-  
+
   std::pair<ExplodedNode*, const GRState *>
   HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
                           ExplodedNode* Pred, GRExprEngine &Eng,
                           SymbolRef Sym, RefVal V, bool &stop);
   // Return statements.
-  
+
   virtual void EvalReturn(ExplodedNodeSet& Dst,
                           GRExprEngine& Engine,
                           GRStmtNodeBuilder& Builder,
@@ -1977,34 +1977,34 @@
   else
     Out << "<pool>";
   Out << ":{";
-    
+
   // Get the contents of the pool.
   if (const ARCounts *cnts = state->get<AutoreleasePoolContents>(Sym))
     for (ARCounts::iterator J=cnts->begin(), EJ=cnts->end(); J != EJ; ++J)
       Out << '(' << J.getKey() << ',' << J.getData() << ')';
 
-  Out << '}';  
+  Out << '}';
 }
 
 void CFRefCount::BindingsPrinter::Print(llvm::raw_ostream& Out,
                                         const GRState* state,
                                         const char* nl, const char* sep) {
-    
+
   RefBindings B = state->get<RefBindings>();
-  
+
   if (!B.isEmpty())
     Out << sep << nl;
-  
+
   for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
     Out << (*I).first << " : ";
     (*I).second.print(Out);
     Out << nl;
   }
-  
+
   // Print the autorelease stack.
   Out << sep << nl << "AR pool stack:";
   ARStack stack = state->get<AutoreleaseStack>();
-  
+
   PrintPool(Out, SymbolRef(), state);  // Print the caller's pool.
   for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
     PrintPool(Out, *I, state);
@@ -2017,117 +2017,117 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
-  
+
   //===-------------===//
   // Bug Descriptions. //
-  //===-------------===//  
-  
+  //===-------------===//
+
   class VISIBILITY_HIDDEN CFRefBug : public BugType {
   protected:
     CFRefCount& TF;
-    
-    CFRefBug(CFRefCount* tf, const char* name) 
-    : BugType(name, "Memory (Core Foundation/Objective-C)"), TF(*tf) {}    
+
+    CFRefBug(CFRefCount* tf, const char* name)
+    : BugType(name, "Memory (Core Foundation/Objective-C)"), TF(*tf) {}
   public:
-    
+
     CFRefCount& getTF() { return TF; }
     const CFRefCount& getTF() const { return TF; }
-    
+
     // FIXME: Eventually remove.
     virtual const char* getDescription() const = 0;
-    
+
     virtual bool isLeak() const { return false; }
   };
-  
+
   class VISIBILITY_HIDDEN UseAfterRelease : public CFRefBug {
   public:
     UseAfterRelease(CFRefCount* tf)
     : CFRefBug(tf, "Use-after-release") {}
-    
+
     const char* getDescription() const {
       return "Reference-counted object is used after it is released";
-    }    
+    }
   };
-  
+
   class VISIBILITY_HIDDEN BadRelease : public CFRefBug {
   public:
     BadRelease(CFRefCount* tf) : CFRefBug(tf, "Bad release") {}
-    
+
     const char* getDescription() const {
       return "Incorrect decrement of the reference count of an "
       "object is not owned at this point by the caller";
     }
   };
-  
+
   class VISIBILITY_HIDDEN DeallocGC : public CFRefBug {
   public:
     DeallocGC(CFRefCount *tf)
       : CFRefBug(tf, "-dealloc called while using garbage collection") {}
-    
+
     const char *getDescription() const {
       return "-dealloc called while using garbage collection";
     }
   };
-  
+
   class VISIBILITY_HIDDEN DeallocNotOwned : public CFRefBug {
   public:
     DeallocNotOwned(CFRefCount *tf)
       : CFRefBug(tf, "-dealloc sent to non-exclusively owned object") {}
-    
+
     const char *getDescription() const {
       return "-dealloc sent to object that may be referenced elsewhere";
     }
-  };  
-  
+  };
+
   class VISIBILITY_HIDDEN OverAutorelease : public CFRefBug {
   public:
-    OverAutorelease(CFRefCount *tf) : 
+    OverAutorelease(CFRefCount *tf) :
       CFRefBug(tf, "Object sent -autorelease too many times") {}
-    
+
     const char *getDescription() const {
       return "Object sent -autorelease too many times";
     }
   };
-  
+
   class VISIBILITY_HIDDEN ReturnedNotOwnedForOwned : public CFRefBug {
   public:
     ReturnedNotOwnedForOwned(CFRefCount *tf) :
       CFRefBug(tf, "Method should return an owned object") {}
-    
+
     const char *getDescription() const {
       return "Object with +0 retain counts returned to caller where a +1 "
              "(owning) retain count is expected";
     }
   };
-  
+
   class VISIBILITY_HIDDEN Leak : public CFRefBug {
     const bool isReturn;
   protected:
     Leak(CFRefCount* tf, const char* name, bool isRet)
     : CFRefBug(tf, name), isReturn(isRet) {}
   public:
-    
+
     const char* getDescription() const { return ""; }
-    
+
     bool isLeak() const { return true; }
   };
-  
+
   class VISIBILITY_HIDDEN LeakAtReturn : public Leak {
   public:
     LeakAtReturn(CFRefCount* tf, const char* name)
     : Leak(tf, name, true) {}
   };
-  
+
   class VISIBILITY_HIDDEN LeakWithinFunction : public Leak {
   public:
     LeakWithinFunction(CFRefCount* tf, const char* name)
     : Leak(tf, name, false) {}
-  };  
-  
+  };
+
   //===---------===//
   // Bug Reports.  //
   //===---------===//
-  
+
   class VISIBILITY_HIDDEN CFRefReport : public RangedBugReport {
   protected:
     SymbolRef Sym;
@@ -2140,30 +2140,30 @@
     CFRefReport(CFRefBug& D, const CFRefCount &tf,
                 ExplodedNode *n, SymbolRef sym, const char* endText)
       : RangedBugReport(D, D.getDescription(), endText, n), Sym(sym), TF(tf) {}
-    
+
     virtual ~CFRefReport() {}
-    
+
     CFRefBug& getBugType() {
       return (CFRefBug&) RangedBugReport::getBugType();
     }
     const CFRefBug& getBugType() const {
       return (const CFRefBug&) RangedBugReport::getBugType();
     }
-    
+
     virtual void getRanges(const SourceRange*& beg, const SourceRange*& end) {
       if (!getBugType().isLeak())
         RangedBugReport::getRanges(beg, end);
       else
         beg = end = 0;
     }
-    
+
     SymbolRef getSymbol() const { return Sym; }
-    
+
     PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
                                     const ExplodedNode* N);
-    
+
     std::pair<const char**,const char**> getExtraDescriptiveText();
-    
+
     PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
                                    const ExplodedNode* PrevN,
                                    BugReporterContext& BRC);
@@ -2176,36 +2176,36 @@
     CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
                     ExplodedNode *n, SymbolRef sym,
                     GRExprEngine& Eng);
-    
+
     PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
                                     const ExplodedNode* N);
-    
+
     SourceLocation getLocation() const { return AllocSite; }
-  };  
+  };
 } // end anonymous namespace
 
 void CFRefCount::RegisterChecks(BugReporter& BR) {
   useAfterRelease = new UseAfterRelease(this);
   BR.Register(useAfterRelease);
-  
+
   releaseNotOwned = new BadRelease(this);
   BR.Register(releaseNotOwned);
-  
+
   deallocGC = new DeallocGC(this);
   BR.Register(deallocGC);
-  
+
   deallocNotOwned = new DeallocNotOwned(this);
   BR.Register(deallocNotOwned);
-  
+
   overAutorelease = new OverAutorelease(this);
   BR.Register(overAutorelease);
-  
+
   returnNotOwnedForOwned = new ReturnedNotOwnedForOwned(this);
   BR.Register(returnNotOwnedForOwned);
-  
+
   // First register "return" leaks.
   const char* name = 0;
-  
+
   if (isGCEnabled())
     name = "Leak of returned object when using garbage collection";
   else if (getLangOptions().getGCMode() == LangOptions::HybridGC)
@@ -2215,13 +2215,13 @@
     assert(getLangOptions().getGCMode() == LangOptions::NonGC);
     name = "Leak of returned object";
   }
-  
+
   leakAtReturn = new LeakAtReturn(this, name);
   BR.Register(leakAtReturn);
-  
+
   // Second, register leaks within a function/method.
   if (isGCEnabled())
-    name = "Leak of object when using garbage collection";  
+    name = "Leak of object when using garbage collection";
   else if (getLangOptions().getGCMode() == LangOptions::HybridGC)
     name = "Leak of object when not using garbage collection (GC) in "
     "dual GC/non-GC code";
@@ -2229,22 +2229,22 @@
     assert(getLangOptions().getGCMode() == LangOptions::NonGC);
     name = "Leak";
   }
-  
+
   leakWithinFunction = new LeakWithinFunction(this, name);
   BR.Register(leakWithinFunction);
-  
+
   // Save the reference to the BugReporter.
   this->BR = &BR;
 }
 
 static const char* Msgs[] = {
   // GC only
-  "Code is compiled to only use garbage collection",    
+  "Code is compiled to only use garbage collection",
   // No GC.
   "Code is compiled to use reference counts",
   // Hybrid, with GC.
   "Code is compiled to use either garbage collection (GC) or reference counts"
-  " (non-GC).  The bug occurs with GC enabled",  
+  " (non-GC).  The bug occurs with GC enabled",
   // Hybrid, without GC
   "Code is compiled to use either garbage collection (GC) or reference counts"
   " (non-GC).  The bug occurs in non-GC mode"
@@ -2252,19 +2252,19 @@
 
 std::pair<const char**,const char**> CFRefReport::getExtraDescriptiveText() {
   CFRefCount& TF = static_cast<CFRefBug&>(getBugType()).getTF();
-  
+
   switch (TF.getLangOptions().getGCMode()) {
     default:
       assert(false);
-      
+
     case LangOptions::GCOnly:
       assert (TF.isGCEnabled());
-      return std::make_pair(&Msgs[0], &Msgs[0]+1);      
-      
+      return std::make_pair(&Msgs[0], &Msgs[0]+1);
+
     case LangOptions::NonGC:
       assert (!TF.isGCEnabled());
       return std::make_pair(&Msgs[1], &Msgs[1]+1);
-      
+
     case LangOptions::HybridGC:
       if (TF.isGCEnabled())
         return std::make_pair(&Msgs[2], &Msgs[2]+1);
@@ -2278,50 +2278,50 @@
   for (llvm::SmallVectorImpl<ArgEffect>::const_iterator I=V.begin(), E=V.end();
        I!=E; ++I)
     if (*I == X) return true;
-  
+
   return false;
 }
 
 PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
                                             const ExplodedNode* PrevN,
                                             BugReporterContext& BRC) {
-  
+
   if (!isa<PostStmt>(N->getLocation()))
     return NULL;
-  
+
   // Check if the type state has changed.
   const GRState *PrevSt = PrevN->getState();
   const GRState *CurrSt = N->getState();
-  
-  const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);  
+
+  const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
   if (!CurrT) return NULL;
-  
+
   const RefVal &CurrV = *CurrT;
   const RefVal *PrevT = PrevSt->get<RefBindings>(Sym);
-  
+
   // Create a string buffer to constain all the useful things we want
   // to tell the user.
   std::string sbuf;
   llvm::raw_string_ostream os(sbuf);
-  
+
   // This is the allocation site since the previous node had no bindings
   // for this symbol.
   if (!PrevT) {
     const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
-    
+
     if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
       // Get the name of the callee (if it is available).
       SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee());
       if (const FunctionDecl* FD = X.getAsFunctionDecl())
         os << "Call to function '" << FD->getNameAsString() <<'\'';
       else
-        os << "function call";      
-    }          
+        os << "function call";
+    }
     else {
       assert (isa<ObjCMessageExpr>(S));
       os << "Method";
     }
-    
+
     if (CurrV.getObjKind() == RetEffect::CF) {
       os << " returns a Core Foundation object with a ";
     }
@@ -2329,10 +2329,10 @@
       assert (CurrV.getObjKind() == RetEffect::ObjC);
       os << " returns an Objective-C object with a ";
     }
-    
+
     if (CurrV.isOwned()) {
       os << "+1 retain count (owning reference).";
-      
+
       if (static_cast<CFRefBug&>(getBugType()).getTF().isGCEnabled()) {
         assert(CurrV.getObjKind() == RetEffect::CF);
         os << "  "
@@ -2343,39 +2343,39 @@
       assert (CurrV.isNotOwned());
       os << "+0 retain count (non-owning reference).";
     }
-    
+
     PathDiagnosticLocation Pos(S, BRC.getSourceManager());
     return new PathDiagnosticEventPiece(Pos, os.str());
   }
-  
+
   // Gather up the effects that were performed on the object at this
   // program point
   llvm::SmallVector<ArgEffect, 2> AEffects;
-  
+
   if (const RetainSummary *Summ =
         TF.getSummaryOfNode(BRC.getNodeResolver().getOriginalNode(N))) {
     // We only have summaries attached to nodes after evaluating CallExpr and
     // ObjCMessageExprs.
     const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
-    
+
     if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
       // Iterate through the parameter expressions and see if the symbol
       // was ever passed as an argument.
       unsigned i = 0;
-      
+
       for (CallExpr::const_arg_iterator AI=CE->arg_begin(), AE=CE->arg_end();
            AI!=AE; ++AI, ++i) {
-        
+
         // Retrieve the value of the argument.  Is it the symbol
         // we are interested in?
         if (CurrSt->getSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym)
           continue;
-        
+
         // We have an argument.  Get the effect!
         AEffects.push_back(Summ->getArg(i));
       }
     }
-    else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {      
+    else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
       if (const Expr *receiver = ME->getReceiver())
         if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
           // The symbol we are tracking is the receiver.
@@ -2383,11 +2383,11 @@
         }
     }
   }
-  
+
   do {
     // Get the previous type state.
     RefVal PrevV = *PrevT;
-    
+
     // Specially handle -dealloc.
     if (!TF.isGCEnabled() && contains(AEffects, Dealloc)) {
       // Determine if the object's reference count was pushed to zero.
@@ -2400,7 +2400,7 @@
         break;
       }
     }
-    
+
     // Specially handle CFMakeCollectable and friends.
     if (contains(AEffects, MakeCollectable)) {
       // Get the name of the function.
@@ -2408,15 +2408,15 @@
       SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
       const FunctionDecl* FD = X.getAsFunctionDecl();
       const std::string& FName = FD->getNameAsString();
-      
+
       if (TF.isGCEnabled()) {
         // Determine if the object's reference count was pushed to zero.
         assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
-        
+
         os << "In GC mode a call to '" << FName
         <<  "' decrements an object's retain count and registers the "
         "object with the garbage collector. ";
-        
+
         if (CurrV.getKind() == RefVal::Released) {
           assert(CurrV.getCount() == 0);
           os << "Since it now has a 0 retain count the object can be "
@@ -2427,67 +2427,67 @@
           "After this call its retain count is +" << CurrV.getCount()
           << '.';
       }
-      else 
+      else
         os << "When GC is not enabled a call to '" << FName
         << "' has no effect on its argument.";
-      
+
       // Nothing more to say.
       break;
     }
-    
-    // Determine if the typestate has changed.  
+
+    // Determine if the typestate has changed.
     if (!(PrevV == CurrV))
       switch (CurrV.getKind()) {
         case RefVal::Owned:
         case RefVal::NotOwned:
-          
+
           if (PrevV.getCount() == CurrV.getCount()) {
             // Did an autorelease message get sent?
             if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
               return 0;
-            
+
             assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
             os << "Object sent -autorelease message";
             break;
           }
-          
+
           if (PrevV.getCount() > CurrV.getCount())
             os << "Reference count decremented.";
           else
             os << "Reference count incremented.";
-          
+
           if (unsigned Count = CurrV.getCount())
             os << " The object now has a +" << Count << " retain count.";
-          
+
           if (PrevV.getKind() == RefVal::Released) {
             assert(TF.isGCEnabled() && CurrV.getCount() > 0);
             os << " The object is not eligible for garbage collection until the "
             "retain count reaches 0 again.";
           }
-          
+
           break;
-          
+
         case RefVal::Released:
           os << "Object released.";
           break;
-          
+
         case RefVal::ReturnedOwned:
           os << "Object returned to caller as an owning reference (single retain "
           "count transferred to caller).";
           break;
-          
+
         case RefVal::ReturnedNotOwned:
           os << "Object returned to caller with a +0 (non-owning) retain count.";
           break;
-          
+
         default:
           return NULL;
       }
-    
+
     // Emit any remaining diagnostics for the argument effects (if any).
     for (llvm::SmallVectorImpl<ArgEffect>::iterator I=AEffects.begin(),
          E=AEffects.end(); I != E; ++I) {
-      
+
       // A bunch of things have alternate behavior under GC.
       if (TF.isGCEnabled())
         switch (*I) {
@@ -2503,25 +2503,25 @@
             continue;
         }
     }
-  } while(0);
-  
+  } while (0);
+
   if (os.str().empty())
     return 0; // We have nothing to say!
 
   const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
   PathDiagnosticLocation Pos(S, BRC.getSourceManager());
   PathDiagnosticPiece* P = new PathDiagnosticEventPiece(Pos, os.str());
-  
+
   // Add the range by scanning the children of the statement for any bindings
   // to Sym.
-  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); 
+  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
        I!=E; ++I)
     if (const Expr* Exp = dyn_cast_or_null<Expr>(*I))
       if (CurrSt->getSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) {
         P->addRange(Exp->getSourceRange());
         break;
       }
-  
+
   return P;
 }
 
@@ -2531,56 +2531,56 @@
     SymbolRef Sym;
     const MemRegion* Binding;
     bool First;
-    
+
   public:
     FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
-    
+
     bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
                        SVal val) {
-      
-      SymbolRef SymV = val.getAsSymbol();    
+
+      SymbolRef SymV = val.getAsSymbol();
       if (!SymV || SymV != Sym)
         return true;
-      
+
       if (Binding) {
         First = false;
         return false;
       }
       else
         Binding = R;
-      
-      return true;    
+
+      return true;
     }
-    
+
     operator bool() { return First && Binding; }
     const MemRegion* getRegion() { return Binding; }
-  };  
+  };
 }
 
 static std::pair<const ExplodedNode*,const MemRegion*>
 GetAllocationSite(GRStateManager& StateMgr, const ExplodedNode* N,
                   SymbolRef Sym) {
-  
+
   // Find both first node that referred to the tracked symbol and the
   // memory location that value was store to.
   const ExplodedNode* Last = N;
-  const MemRegion* FirstBinding = 0;  
-  
+  const MemRegion* FirstBinding = 0;
+
   while (N) {
     const GRState* St = N->getState();
     RefBindings B = St->get<RefBindings>();
-    
+
     if (!B.lookup(Sym))
       break;
-    
+
     FindUniqueBinding FB(Sym);
-    StateMgr.iterBindings(St, FB);      
-    if (FB) FirstBinding = FB.getRegion();      
-    
+    StateMgr.iterBindings(St, FB);
+    if (FB) FirstBinding = FB.getRegion();
+
     Last = N;
-    N = N->pred_empty() ? NULL : *(N->pred_begin());    
+    N = N->pred_empty() ? NULL : *(N->pred_begin());
   }
-  
+
   return std::make_pair(Last, FirstBinding);
 }
 
@@ -2596,36 +2596,36 @@
 PathDiagnosticPiece*
 CFRefLeakReport::getEndPath(BugReporterContext& BRC,
                             const ExplodedNode* EndN){
-  
+
   // Tell the BugReporterContext to report cases when the tracked symbol is
   // assigned to different variables, etc.
   BRC.addNotableSymbol(Sym);
-  
+
   // We are reporting a leak.  Walk up the graph to get to the first node where
   // the symbol appeared, and also get the first VarDecl that tracked object
   // is stored to.
   const ExplodedNode* AllocNode = 0;
   const MemRegion* FirstBinding = 0;
-  
+
   llvm::tie(AllocNode, FirstBinding) =
     GetAllocationSite(BRC.getStateManager(), EndN, Sym);
-  
-  // Get the allocate site.  
+
+  // Get the allocate site.
   assert(AllocNode);
   const Stmt* FirstStmt = cast<PostStmt>(AllocNode->getLocation()).getStmt();
-  
+
   SourceManager& SMgr = BRC.getSourceManager();
   unsigned AllocLine =SMgr.getInstantiationLineNumber(FirstStmt->getLocStart());
-  
+
   // Compute an actual location for the leak.  Sometimes a leak doesn't
   // occur at an actual statement (e.g., transition between blocks; end
   // of function) so we need to walk the graph and compute a real location.
   const ExplodedNode* LeakN = EndN;
   PathDiagnosticLocation L;
-  
+
   while (LeakN) {
     ProgramPoint P = LeakN->getLocation();
-    
+
     if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
       L = PathDiagnosticLocation(PS->getStmt()->getLocStart(), SMgr);
       break;
@@ -2636,26 +2636,26 @@
         break;
       }
     }
-    
+
     LeakN = LeakN->succ_empty() ? 0 : *(LeakN->succ_begin());
   }
-  
+
   if (!L.isValid()) {
     const Decl &D = BRC.getCodeDecl();
     L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);
   }
-  
+
   std::string sbuf;
   llvm::raw_string_ostream os(sbuf);
-  
+
   os << "Object allocated on line " << AllocLine;
-  
+
   if (FirstBinding)
-    os << " and stored into '" << FirstBinding->getString() << '\'';  
-  
+    os << " and stored into '" << FirstBinding->getString() << '\'';
+
   // Get the retain count.
   const RefVal* RV = EndN->getState()->get<RefBindings>(Sym);
-  
+
   if (RV->getKind() == RefVal::ErrorLeakReturned) {
     // FIXME: Per comments in rdar://6320065, "create" only applies to CF
     // ojbects.  Only "copy", "alloc", "retain" and "new" transfer ownership
@@ -2678,16 +2678,15 @@
   else
     os << " is no longer referenced after this point and has a retain count of"
           " +" << RV->getCount() << " (object leaked)";
-  
+
   return new PathDiagnosticEventPiece(L, os.str());
 }
 
 CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
                                  ExplodedNode *n,
                                  SymbolRef sym, GRExprEngine& Eng)
-: CFRefReport(D, tf, n, sym)
-{
-  
+: CFRefReport(D, tf, n, sym) {
+
   // Most bug reports are cached at the location where they occured.
   // With leaks, we want to unique them by the location where they were
   // allocated, and only report a single path.  To do this, we need to find
@@ -2697,14 +2696,14 @@
   // that all ancestor nodes that represent the allocation site have the
   // same SourceLocation.
   const ExplodedNode* AllocNode = 0;
-  
+
   llvm::tie(AllocNode, AllocBinding) =  // Set AllocBinding.
     GetAllocationSite(Eng.getStateManager(), getEndNode(), getSymbol());
-  
+
   // Get the SourceLocation for the allocation site.
   ProgramPoint P = AllocNode->getLocation();
   AllocSite = cast<PostStmt>(P).getStmt()->getLocStart();
-  
+
   // Fill in the description of the bug.
   Description.clear();
   llvm::raw_string_ostream os(Description);
@@ -2713,9 +2712,9 @@
   os << "Potential leak ";
   if (tf.isGCEnabled()) {
     os << "(when using garbage collection) ";
-  }  
+  }
   os << "of an object allocated on line " << AllocLine;
-  
+
   // FIXME: AllocBinding doesn't get populated for RegionStore yet.
   if (AllocBinding)
     os << " and stored into '" << AllocBinding->getString() << '\'';
@@ -2737,16 +2736,16 @@
   /// more specific than id.
   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
     if (const ObjCObjectPointerType *PT = RetTy->getAsObjCObjectPointerType())
-      if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() || 
+      if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
           PT->isObjCClassType()) {
         // At this point we know the return type of the message expression is
         // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
         // is a call to a class method whose type we can resolve.  In such
         // cases, promote the return type to XXX* (where XXX is the class).
-        const ObjCInterfaceDecl *D = ME->getClassInfo().first;  
+        const ObjCInterfaceDecl *D = ME->getClassInfo().first;
         return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
       }
-  
+
   return RetTy;
 }
 
@@ -2758,7 +2757,7 @@
                              const RetainSummary& Summ,
                              ExprIterator arg_beg, ExprIterator arg_end,
                              ExplodedNode* Pred) {
-  
+
   // Get the state.
   const GRState *state = Builder.GetState(Pred);
 
@@ -2766,10 +2765,10 @@
   RefVal::Kind hasErr = (RefVal::Kind) 0;
   unsigned idx = 0;
   Expr* ErrorExpr = NULL;
-  SymbolRef ErrorSym = 0;                                        
-  
-  for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {    
-    SVal V = state->getSValAsScalarOrLoc(*I);    
+  SymbolRef ErrorSym = 0;
+
+  for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
+    SVal V = state->getSValAsScalarOrLoc(*I);
     SymbolRef Sym = V.getAsLocSymbol();
 
     if (Sym)
@@ -2779,7 +2778,7 @@
           ErrorExpr = *I;
           ErrorSym = Sym;
           break;
-        }        
+        }
         continue;
       }
 
@@ -2787,14 +2786,14 @@
       if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
         if (Summ.getArg(idx) == DoNothingByRef)
           continue;
-        
-        // Invalidate the value of the variable passed by reference.        
-        
+
+        // Invalidate the value of the variable passed by reference.
+
         // FIXME: We can have collisions on the conjured symbol if the
         //  expression *I also creates conjured symbols.  We probably want
         //  to identify conjured symbols by an expression pair: the enclosing
         //  expression (the context) and the expression itself.  This should
-        //  disambiguate conjured symbols. 
+        //  disambiguate conjured symbols.
         unsigned Count = Builder.getCurrentBlockCount();
         StoreManager& StoreMgr = Eng.getStateManager().getStoreManager();
 
@@ -2825,9 +2824,9 @@
 
         // Is the invalidated variable something that we were tracking?
         SymbolRef Sym = state->getSValAsScalarOrLoc(R).getAsLocSymbol();
-        
+
         // Remove any existing reference-count binding.
-        if (Sym) 
+        if (Sym)
           state = state->remove<RefBindings>(Sym);
 
         state = StoreMgr.InvalidateRegion(state, R, *I, Count);
@@ -2845,9 +2844,9 @@
       // We should bind it to UnknownVal explicitly. Otherwise default value
       // may be loaded.
       state = state->unbindLoc(cast<nonloc::LocAsInteger>(V).getLoc());
-  } 
-  
-  // Evaluate the effect on the message receiver.  
+  }
+
+  // Evaluate the effect on the message receiver.
   if (!ErrorExpr && Receiver) {
     SymbolRef Sym = state->getSValAsScalarOrLoc(Receiver).getAsLocSymbol();
     if (Sym) {
@@ -2860,17 +2859,17 @@
       }
     }
   }
-  
-  // Process any errors.  
+
+  // Process any errors.
   if (hasErr) {
     ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, state,
                         hasErr, ErrorSym);
     return;
   }
-  
-  // Consult the summary for the return value.  
+
+  // Consult the summary for the return value.
   RetEffect RE = Summ.getRetEffect();
-  
+
   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
     assert(Receiver);
     SVal V = state->getSValAsScalarOrLoc(Receiver);
@@ -2883,32 +2882,32 @@
 
     if (!found)
       RE = RetEffect::MakeNoRet();
-  } 
-  
+  }
+
   switch (RE.getKind()) {
     default:
       assert (false && "Unhandled RetEffect."); break;
-      
-    case RetEffect::NoRet: {      
+
+    case RetEffect::NoRet: {
       // Make up a symbol for the return value (not reference counted).
       // FIXME: Most of this logic is not specific to the retain/release
       // checker.
-      
+
       // FIXME: We eventually should handle structs and other compound types
       // that are returned by value.
-      
+
       QualType T = Ex->getType();
-      
+
       if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
         unsigned Count = Builder.getCurrentBlockCount();
         ValueManager &ValMgr = Eng.getValueManager();
         SVal X = ValMgr.getConjuredSymbolVal(Ex, T, Count);
         state = state->BindExpr(Ex, X, false);
-      }      
-      
+      }
+
       break;
     }
-      
+
     case RetEffect::Alias: {
       unsigned idx = RE.getIndex();
       assert (arg_end >= arg_beg);
@@ -2917,20 +2916,20 @@
       state = state->BindExpr(Ex, V, false);
       break;
     }
-      
+
     case RetEffect::ReceiverAlias: {
       assert (Receiver);
       SVal V = state->getSValAsScalarOrLoc(Receiver);
       state = state->BindExpr(Ex, V, false);
       break;
     }
-      
+
     case RetEffect::OwnedAllocatedSymbol:
     case RetEffect::OwnedSymbol: {
       unsigned Count = Builder.getCurrentBlockCount();
-      ValueManager &ValMgr = Eng.getValueManager();      
+      ValueManager &ValMgr = Eng.getValueManager();
       SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
-      QualType RetT = GetReturnType(Ex, ValMgr.getContext());      
+      QualType RetT = GetReturnType(Ex, ValMgr.getContext());
       state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
                                                             RetT));
       state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false);
@@ -2941,31 +2940,31 @@
       if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) {
         bool isFeasible;
         state = state.Assume(loc::SymbolVal(Sym), true, isFeasible);
-        assert(isFeasible && "Cannot assume fresh symbol is non-null.");        
+        assert(isFeasible && "Cannot assume fresh symbol is non-null.");
       }
 #endif
-      
+
       break;
     }
-    
+
     case RetEffect::GCNotOwnedSymbol:
     case RetEffect::NotOwnedSymbol: {
       unsigned Count = Builder.getCurrentBlockCount();
       ValueManager &ValMgr = Eng.getValueManager();
       SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
-      QualType RetT = GetReturnType(Ex, ValMgr.getContext());      
+      QualType RetT = GetReturnType(Ex, ValMgr.getContext());
       state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
                                                                RetT));
       state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false);
       break;
     }
   }
-  
+
   // Generate a sink node if we are at the end of a path.
   ExplodedNode *NewNode =
     Summ.isEndPath() ? Builder.MakeSinkNode(Dst, Ex, Pred, state)
                      : Builder.MakeNode(Dst, Ex, Pred, state);
-  
+
   // Annotate the edge with summary we used.
   if (NewNode) SummaryLog[NewNode] = &Summ;
 }
@@ -2977,9 +2976,9 @@
                           CallExpr* CE, SVal L,
                           ExplodedNode* Pred) {
   const FunctionDecl* FD = L.getAsFunctionDecl();
-  RetainSummary* Summ = !FD ? Summaries.getDefaultSummary() 
+  RetainSummary* Summ = !FD ? Summaries.getDefaultSummary()
                         : Summaries.getSummary(const_cast<FunctionDecl*>(FD));
-  
+
   assert(Summ);
   EvalSummary(Dst, Eng, Builder, CE, 0, *Summ,
               CE->arg_begin(), CE->arg_end(), Pred);
@@ -2989,9 +2988,9 @@
                                      GRExprEngine& Eng,
                                      GRStmtNodeBuilder& Builder,
                                      ObjCMessageExpr* ME,
-                                     ExplodedNode* Pred) {  
+                                     ExplodedNode* Pred) {
   RetainSummary* Summ = 0;
-  
+
   if (Expr* Receiver = ME->getReceiver()) {
     // We need the type-information of the tracked receiver object
     // Retrieve it from the state.
@@ -3005,7 +3004,7 @@
     SVal V = St->getSValAsScalarOrLoc(Receiver);
 
     SymbolRef Sym = V.getAsLocSymbol();
-    
+
     if (Sym) {
       if (const RefVal* T  = St->get<RefBindings>(Sym)) {
         if (const ObjCObjectPointerType* PT =
@@ -3028,21 +3027,21 @@
 
     // Special-case: are we sending a mesage to "self"?
     //  This is a hack.  When we have full-IP this should be removed.
-    if (isa<ObjCMethodDecl>(Pred->getLocationContext()->getDecl())) {      
+    if (isa<ObjCMethodDecl>(Pred->getLocationContext()->getDecl())) {
       if (Expr* Receiver = ME->getReceiver()) {
         SVal X = St->getSValAsScalarOrLoc(Receiver);
-        if (loc::MemRegionVal* L = dyn_cast<loc::MemRegionVal>(&X)) {          
+        if (loc::MemRegionVal* L = dyn_cast<loc::MemRegionVal>(&X)) {
           // Get the region associated with 'self'.
-          const LocationContext *LC = Pred->getLocationContext();          
+          const LocationContext *LC = Pred->getLocationContext();
           if (const ImplicitParamDecl *SelfDecl = LC->getSelfDecl()) {
-            SVal SelfVal = St->getSVal(St->getRegion(SelfDecl, LC));          
+            SVal SelfVal = St->getSVal(St->getRegion(SelfDecl, LC));
             if (L->getBaseRegion() == SelfVal.getAsRegion()) {
               // Update the summary to make the default argument effect
               // 'StopTracking'.
               Summ = Summaries.copySummary(Summ);
               Summ->setDefaultArgEffect(StopTracking);
             }
-          } 
+          }
         }
       }
     }
@@ -3070,18 +3069,18 @@
   }
 };
 } // end anonymous namespace
-  
 
-void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {  
-  // Are we storing to something that causes the value to "escape"?  
+
+void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
+  // Are we storing to something that causes the value to "escape"?
   bool escapes = false;
-  
+
   // A value escapes in three possible cases (this may change):
   //
   // (1) we are binding to something that is not a memory region.
   // (2) we are binding to a memregion that does not have stack storage
   // (3) we are binding to a memregion with stack storage that the store
-  //     does not understand.  
+  //     does not understand.
   const GRState *state = B.getState();
 
   if (!isa<loc::MemRegionVal>(location))
@@ -3089,7 +3088,7 @@
   else {
     const MemRegion* R = cast<loc::MemRegionVal>(location).getRegion();
     escapes = !R->hasStackStorage();
-    
+
     if (!escapes) {
       // To test (3), generate a new state with the binding removed.  If it is
       // the same state, then it escapes (since the store cannot represent
@@ -3116,35 +3115,35 @@
                             GRStmtNodeBuilder& Builder,
                             ReturnStmt* S,
                             ExplodedNode* Pred) {
-  
+
   Expr* RetE = S->getRetValue();
   if (!RetE)
     return;
-  
+
   const GRState *state = Builder.GetState(Pred);
   SymbolRef Sym = state->getSValAsScalarOrLoc(RetE).getAsLocSymbol();
-  
+
   if (!Sym)
     return;
-  
+
   // Get the reference count binding (if any).
   const RefVal* T = state->get<RefBindings>(Sym);
-  
+
   if (!T)
     return;
-  
-  // Change the reference count.  
-  RefVal X = *T;  
-  
-  switch (X.getKind()) { 
-    case RefVal::Owned: { 
+
+  // Change the reference count.
+  RefVal X = *T;
+
+  switch (X.getKind()) {
+    case RefVal::Owned: {
       unsigned cnt = X.getCount();
       assert (cnt > 0);
       X.setCount(cnt - 1);
       X = X ^ RefVal::ReturnedOwned;
       break;
     }
-      
+
     case RefVal::NotOwned: {
       unsigned cnt = X.getCount();
       if (cnt) {
@@ -3156,39 +3155,39 @@
       }
       break;
     }
-      
-    default: 
+
+    default:
       return;
   }
-  
+
   // Update the binding.
   state = state->set<RefBindings>(Sym, X);
   Pred = Builder.MakeNode(Dst, S, Pred, state);
-  
+
   // Did we cache out?
   if (!Pred)
     return;
-  
+
   // Update the autorelease counts.
   static unsigned autoreleasetag = 0;
   GenericNodeBuilder Bd(Builder, S, &autoreleasetag);
   bool stop = false;
   llvm::tie(Pred, state) = HandleAutoreleaseCounts(state , Bd, Pred, Eng, Sym,
                                                    X, stop);
-  
+
   // Did we cache out?
   if (!Pred || stop)
     return;
-  
+
   // Get the updated binding.
   T = state->get<RefBindings>(Sym);
   assert(T);
   X = *T;
-    
+
   // Any leaks or other errors?
   if (X.isReturnedOwned() && X.getCount() == 0) {
-    const Decl *CD = Eng.getAnalysisManager().getCodeDecl();    
-    if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {      
+    const Decl *CD = Eng.getAnalysisManager().getCodeDecl();
+    if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
       const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
       RetEffect RE = Summ.getRetEffect();
       bool hasError = false;
@@ -3200,20 +3199,20 @@
           // a leak (as the caller expects a GC'ed object) because no
           // method should return ownership unless it returns a CF object.
           X = X ^ RefVal::ErrorGCLeakReturned;
-          
+
           // Keep this false until this is properly tested.
           hasError = true;
         }
         else if (!RE.isOwned()) {
           // Either we are using GC and the returned object is a CF type
           // or we aren't using GC.  In either case, we expect that the
-          // enclosing method is expected to return ownership.        
+          // enclosing method is expected to return ownership.
           hasError = true;
           X = X ^ RefVal::ErrorLeakReturned;
         }
       }
-      
-      if (hasError) {        
+
+      if (hasError) {
         // Generate an error node.
         static int ReturnOwnLeakTag = 0;
         state = state->set<RefBindings>(Sym, X);
@@ -3227,16 +3226,16 @@
           BR->EmitReport(report);
         }
       }
-    } 
+    }
   }
   else if (X.isReturnedNotOwned()) {
-    const Decl *CD = Eng.getAnalysisManager().getCodeDecl();    
+    const Decl *CD = Eng.getAnalysisManager().getCodeDecl();
     if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
       const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
       if (Summ.getRetEffect().isOwned()) {
         // Trying to return a not owned object to a caller expecting an
         // owned object.
-        
+
         static int ReturnNotOwnedForOwnedTag = 0;
         state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
         if (ExplodedNode *N =
@@ -3261,18 +3260,18 @@
   // FIXME: We may add to the interface of EvalAssume the list of symbols
   //  whose assumptions have changed.  For now we just iterate through the
   //  bindings and check if any of the tracked symbols are NULL.  This isn't
-  //  too bad since the number of symbols we will track in practice are 
+  //  too bad since the number of symbols we will track in practice are
   //  probably small and EvalAssume is only called at branches and a few
   //  other places.
   RefBindings B = state->get<RefBindings>();
-  
+
   if (B.isEmpty())
     return state;
-  
-  bool changed = false;  
+
+  bool changed = false;
   RefBindings::Factory& RefBFactory = state->get_context<RefBindings>();
 
-  for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {    
+  for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
     // Check if the symbol is null (or equal to any constant).
     // If this is the case, stop tracking the symbol.
     if (state->getSymVal(I.getKey())) {
@@ -3280,10 +3279,10 @@
       B = RefBFactory.Remove(B, I.getKey());
     }
   }
-  
+
   if (changed)
     state = state->set<RefBindings>(B);
-  
+
   return state;
 }
 
@@ -3297,21 +3296,21 @@
     case IncRefMsg: E = isGCEnabled() ? DoNothing : IncRef; break;
     case DecRefMsg: E = isGCEnabled() ? DoNothing : DecRef; break;
     case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break;
-    case NewAutoreleasePool: E = isGCEnabled() ? DoNothing : 
+    case NewAutoreleasePool: E = isGCEnabled() ? DoNothing :
                                                  NewAutoreleasePool; break;
   }
-  
+
   // Handle all use-after-releases.
   if (!isGCEnabled() && V.getKind() == RefVal::Released) {
     V = V ^ RefVal::ErrorUseAfterRelease;
     hasErr = V.getKind();
     return state->set<RefBindings>(sym, V);
-  }      
-  
+  }
+
   switch (E) {
     default:
       assert (false && "Unhandled CFRef transition.");
-      
+
     case Dealloc:
       // Any use of -dealloc in GC is *bad*.
       if (isGCEnabled()) {
@@ -3319,7 +3318,7 @@
         hasErr = V.getKind();
         break;
       }
-      
+
       switch (V.getKind()) {
         default:
           assert(false && "Invalid case.");
@@ -3332,13 +3331,13 @@
           V = V ^ RefVal::ErrorDeallocNotOwned;
           hasErr = V.getKind();
           break;
-      }      
+      }
       break;
 
     case NewAutoreleasePool:
       assert(!isGCEnabled());
       return state->add<AutoreleaseStack>(sym);
-      
+
     case MayEscape:
       if (V.getKind() == RefVal::Owned) {
         V = V ^ RefVal::NotOwned;
@@ -3346,7 +3345,7 @@
       }
 
       // Fall-through.
-      
+
     case DoNothingByRef:
     case DoNothing:
       return state;
@@ -3354,7 +3353,7 @@
     case Autorelease:
       if (isGCEnabled())
         return state;
-      
+
       // Update the autorelease counts.
       state = SendAutorelease(state, ARCountFactory, sym);
       V = V.autorelease();
@@ -3363,7 +3362,7 @@
     case StopTracking:
       return state->remove<RefBindings>(sym);
 
-    case IncRef:      
+    case IncRef:
       switch (V.getKind()) {
         default:
           assert(false);
@@ -3371,15 +3370,15 @@
         case RefVal::Owned:
         case RefVal::NotOwned:
           V = V + 1;
-          break;          
+          break;
         case RefVal::Released:
           // Non-GC cases are handled above.
           assert(isGCEnabled());
           V = (V ^ RefVal::Owned) + 1;
           break;
-      }      
+      }
       break;
-      
+
     case SelfOwn:
       V = V ^ RefVal::NotOwned;
       // Fall-through.
@@ -3394,23 +3393,23 @@
           if (V.getCount() == 1) V = V ^ RefVal::Released;
           V = V - 1;
           break;
-          
+
         case RefVal::NotOwned:
           if (V.getCount() > 0)
             V = V - 1;
           else {
             V = V ^ RefVal::ErrorReleaseNotOwned;
             hasErr = V.getKind();
-          }          
+          }
           break;
-          
+
         case RefVal::Released:
           // Non-GC cases are handled above.
           assert(isGCEnabled());
           V = V ^ RefVal::ErrorUseAfterRelease;
           hasErr = V.getKind();
-          break;  
-      }      
+          break;
+      }
       break;
   }
   return state->set<RefBindings>(sym, V);
@@ -3425,22 +3424,22 @@
                                     ExplodedNode* Pred,
                                     GRExprEngine &Eng,
                                     SymbolRef Sym, RefVal V, bool &stop) {
- 
+
   unsigned ACnt = V.getAutoreleaseCount();
   stop = false;
 
   // No autorelease counts?  Nothing to be done.
   if (!ACnt)
     return std::make_pair(Pred, state);
-  
-  assert(!isGCEnabled() && "Autorelease counts in GC mode?");  
+
+  assert(!isGCEnabled() && "Autorelease counts in GC mode?");
   unsigned Cnt = V.getCount();
-  
+
   // FIXME: Handle sending 'autorelease' to already released object.
 
   if (V.getKind() == RefVal::ReturnedOwned)
     ++Cnt;
-  
+
   if (ACnt <= Cnt) {
     if (ACnt == Cnt) {
       V.clearCounts();
@@ -3457,7 +3456,7 @@
     ExplodedNode *N = Bd.MakeNode(state, Pred);
     stop = (N == 0);
     return std::make_pair(N, state);
-  }    
+  }
 
   // Woah!  More autorelease counts then retain counts left.
   // Emit hard error.
@@ -3467,7 +3466,7 @@
 
   if (ExplodedNode *N = Bd.MakeNode(state, Pred)) {
     N->markAsSink();
-    
+
     std::string sbuf;
     llvm::raw_string_ostream os(sbuf);
     os << "Object over-autoreleased: object was sent -autorelease";
@@ -3479,26 +3478,26 @@
     else
       os << "+" << V.getCount();
     os << " retain counts";
-    
+
     CFRefReport *report =
       new CFRefReport(*static_cast<CFRefBug*>(overAutorelease),
                       *this, N, Sym, os.str().c_str());
     BR->EmitReport(report);
   }
-  
+
   return std::make_pair((ExplodedNode*)0, state);
 }
 
 const GRState *
 CFRefCount::HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
                               llvm::SmallVectorImpl<SymbolRef> &Leaked) {
-  
-  bool hasLeak = V.isOwned() || 
+
+  bool hasLeak = V.isOwned() ||
   ((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
-  
+
   if (!hasLeak)
     return state->remove<RefBindings>(sid);
-  
+
   Leaked.push_back(sid);
   return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
 }
@@ -3509,49 +3508,49 @@
                          GenericNodeBuilder &Builder,
                          GRExprEngine& Eng,
                          ExplodedNode *Pred) {
-  
+
   if (Leaked.empty())
     return Pred;
-  
+
   // Generate an intermediate node representing the leak point.
   ExplodedNode *N = Builder.MakeNode(state, Pred);
-  
+
   if (N) {
     for (llvm::SmallVectorImpl<SymbolRef>::iterator
          I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
-      
-      CFRefBug *BT = static_cast<CFRefBug*>(Pred ? leakWithinFunction 
+
+      CFRefBug *BT = static_cast<CFRefBug*>(Pred ? leakWithinFunction
                                                  : leakAtReturn);
       assert(BT && "BugType not initialized.");
       CFRefLeakReport* report = new CFRefLeakReport(*BT, *this, N, *I, Eng);
       BR->EmitReport(report);
     }
   }
-  
+
   return N;
 }
 
 void CFRefCount::EvalEndPath(GRExprEngine& Eng,
                              GREndPathNodeBuilder& Builder) {
-  
+
   const GRState *state = Builder.getState();
   GenericNodeBuilder Bd(Builder);
-  RefBindings B = state->get<RefBindings>();  
+  RefBindings B = state->get<RefBindings>();
   ExplodedNode *Pred = 0;
 
   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
     bool stop = false;
     llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng,
                                                      (*I).first,
-                                                     (*I).second, stop);   
+                                                     (*I).second, stop);
 
     if (stop)
       return;
   }
-  
-  B = state->get<RefBindings>();  
-  llvm::SmallVector<SymbolRef, 10> Leaked;  
-  
+
+  B = state->get<RefBindings>();
+  llvm::SmallVector<SymbolRef, 10> Leaked;
+
   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
     state = HandleSymbolDeath(state, (*I).first, (*I).second, Leaked);
 
@@ -3567,7 +3566,7 @@
                                  SymbolReaper& SymReaper) {
 
   RefBindings B = state->get<RefBindings>();
-  
+
   // Update counts from autorelease pools
   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
        E = SymReaper.dead_end(); I != E; ++I) {
@@ -3583,32 +3582,32 @@
         return;
     }
   }
-  
+
   B = state->get<RefBindings>();
   llvm::SmallVector<SymbolRef, 10> Leaked;
-  
+
   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
-       E = SymReaper.dead_end(); I != E; ++I) {    
+       E = SymReaper.dead_end(); I != E; ++I) {
       if (const RefVal* T = B.lookup(*I))
         state = HandleSymbolDeath(state, *I, *T, Leaked);
-  }    
-  
+  }
+
   static unsigned LeakPPTag = 0;
   {
     GenericNodeBuilder Bd(Builder, S, &LeakPPTag);
     Pred = ProcessLeaks(state, Leaked, Bd, Eng, Pred);
   }
-  
+
   // Did we cache out?
   if (!Pred)
     return;
-  
+
   // Now generate a new node that nukes the old bindings.
   RefBindings::Factory& F = state->get_context<RefBindings>();
-  
+
   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
        E = SymReaper.dead_end(); I!=E; ++I) B = F.Remove(B, *I);
-  
+
   state = state->set<RefBindings>(B);
   Builder.MakeNode(Dst, S, Pred, state);
 }
@@ -3621,19 +3620,19 @@
                                      RefVal::Kind hasErr, SymbolRef Sym) {
   Builder.BuildSinks = true;
   ExplodedNode *N  = Builder.MakeNode(Dst, NodeExpr, Pred, St);
-  
+
   if (!N)
     return;
-  
+
   CFRefBug *BT = 0;
-  
+
   switch (hasErr) {
     default:
       assert(false && "Unhandled error.");
       return;
     case RefVal::ErrorUseAfterRelease:
       BT = static_cast<CFRefBug*>(useAfterRelease);
-      break;      
+      break;
     case RefVal::ErrorReleaseNotOwned:
       BT = static_cast<CFRefBug*>(releaseNotOwned);
       break;
@@ -3644,7 +3643,7 @@
       BT = static_cast<CFRefBug*>(deallocNotOwned);
       break;
   }
-    
+
   CFRefReport *report = new CFRefReport(*BT, *this, N, Sym);
   report->addRange(ErrorExpr->getSourceRange());
   BR->EmitReport(report);
@@ -3657,4 +3656,4 @@
 GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
                                          const LangOptions& lopts) {
   return new CFRefCount(Ctx, GCEnabled, lopts);
-}  
+}
