diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 86a52fc..a6918e4 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/Frontend/PCHWriter.h"
 #include "../Sema/Sema.h" // FIXME: move header into include/clang/Sema
-#include "../Sema/IdentifierResolver.h" // FIXME: move header 
+#include "../Sema/IdentifierResolver.h" // FIXME: move header
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclContextInternals.h"
@@ -50,7 +50,7 @@
     /// \brief Type code that corresponds to the record generated.
     pch::TypeCode Code;
 
-    PCHTypeWriter(PCHWriter &Writer, PCHWriter::RecordData &Record) 
+    PCHTypeWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
       : Writer(Writer), Record(Record), Code(pch::TYPE_EXT_QUAL) { }
 
     void VisitArrayType(const ArrayType *T);
@@ -92,7 +92,7 @@
 }
 
 void PCHTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
-  Writer.AddTypeRef(T->getPointeeType(), Record);  
+  Writer.AddTypeRef(T->getPointeeType(), Record);
   Code = pch::TYPE_BLOCK_POINTER;
 }
 
@@ -107,8 +107,8 @@
 }
 
 void PCHTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
-  Writer.AddTypeRef(T->getPointeeType(), Record);  
-  Writer.AddTypeRef(QualType(T->getClass(), 0), Record);  
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
   Code = pch::TYPE_MEMBER_POINTER;
 }
 
@@ -211,7 +211,7 @@
 
 void PCHTypeWriter::VisitTagType(const TagType *T) {
   Writer.AddDeclRef(T->getDecl(), Record);
-  assert(!T->isBeingDefined() && 
+  assert(!T->isBeingDefined() &&
          "Cannot serialize in the middle of a type definition");
 }
 
@@ -231,7 +231,7 @@
   Code = pch::TYPE_ELABORATED;
 }
 
-void 
+void
 PCHTypeWriter::VisitTemplateSpecializationType(
                                        const TemplateSpecializationType *T) {
   // FIXME: Serialize this type (C++ only)
@@ -254,7 +254,7 @@
 
 void
 PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
-  Writer.AddTypeRef(T->getPointeeType(), Record);  
+  Writer.AddTypeRef(T->getPointeeType(), Record);
   Record.push_back(T->getNumProtocols());
   for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
        E = T->qual_end(); I != E; ++I)
@@ -362,14 +362,14 @@
   RECORD(STMT_OBJC_AT_THROW);
 #undef RECORD
 }
-  
+
 void PCHWriter::WriteBlockInfoBlock() {
   RecordData Record;
   Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3);
-  
+
 #define BLOCK(X) EmitBlockID(pch::X ## _ID, #X, Stream, Record)
 #define RECORD(X) EmitRecordID(pch::X, #X, Stream, Record)
- 
+
   // PCH Top-Level Block.
   BLOCK(PCH_BLOCK);
   RECORD(ORIGINAL_FILE_NAME);
@@ -392,7 +392,7 @@
   RECORD(STAT_CACHE);
   RECORD(EXT_VECTOR_DECLS);
   RECORD(COMMENT_RANGES);
-  
+
   // SourceManager Block.
   BLOCK(SOURCE_MANAGER_BLOCK);
   RECORD(SM_SLOC_FILE_ENTRY);
@@ -401,7 +401,7 @@
   RECORD(SM_SLOC_INSTANTIATION_ENTRY);
   RECORD(SM_LINE_TABLE);
   RECORD(SM_HEADER_FILE_INFO);
-  
+
   // Preprocessor Block.
   BLOCK(PREPROCESSOR_BLOCK);
   RECORD(PP_MACRO_OBJECT_LIKE);
@@ -475,7 +475,7 @@
 
 /// \brief Adjusts the given filename to only write out the portion of the
 /// filename that is not part of the system root directory.
-/// 
+///
 /// \param Filename the file name to adjust.
 ///
 /// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and
@@ -483,29 +483,29 @@
 ///
 /// \returns either the original filename (if it needs no adjustment) or the
 /// adjusted filename (which points into the @p Filename parameter).
-static const char * 
+static const char *
 adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) {
   assert(Filename && "No file name to adjust?");
-  
+
   if (!isysroot)
     return Filename;
-  
+
   // Verify that the filename and the system root have the same prefix.
   unsigned Pos = 0;
   for (; Filename[Pos] && isysroot[Pos]; ++Pos)
     if (Filename[Pos] != isysroot[Pos])
       return Filename; // Prefixes don't match.
-  
+
   // We hit the end of the filename before we hit the end of the system root.
   if (!Filename[Pos])
     return Filename;
-  
+
   // If the file name has a '/' at the current position, skip over the '/'.
   // We distinguish sysroot-based includes from absolute includes by the
   // absence of '/' at the beginning of sysroot-based includes.
   if (Filename[Pos] == '/')
     ++Pos;
-  
+
   return Filename + Pos;
 }
 
@@ -524,7 +524,7 @@
   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
   unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
-  
+
   RecordData Record;
   Record.push_back(pch::METADATA);
   Record.push_back(pch::VERSION_MAJOR);
@@ -534,7 +534,7 @@
   Record.push_back(isysroot != 0);
   const std::string &TripleStr = Target.getTriple().getTriple();
   Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, TripleStr);
-  
+
   // Original file name
   SourceManager &SM = Context.getSourceManager();
   if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
@@ -545,7 +545,7 @@
 
     llvm::sys::Path MainFilePath(MainFile->getName());
     std::string MainFileName;
-  
+
     if (!MainFilePath.isAbsolute()) {
       llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
       P.appendComponent(MainFilePath.str());
@@ -555,7 +555,7 @@
     }
 
     const char *MainFileNameStr = MainFileName.c_str();
-    MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, 
+    MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr,
                                                       isysroot);
     RecordData Record;
     Record.push_back(pch::ORIGINAL_FILE_NAME);
@@ -579,11 +579,11 @@
   Record.push_back(LangOpts.CPlusPlus);  // C++ Support
   Record.push_back(LangOpts.CPlusPlus0x);  // C++0x Support
   Record.push_back(LangOpts.CXXOperatorNames);  // Treat C++ operator names as keywords.
-    
+
   Record.push_back(LangOpts.ObjC1);  // Objective-C 1 support enabled.
   Record.push_back(LangOpts.ObjC2);  // Objective-C 2 support enabled.
   Record.push_back(LangOpts.ObjCNonFragileABI);  // Objective-C modern abi enabled
-    
+
   Record.push_back(LangOpts.PascalStrings);  // Allow Pascal strings
   Record.push_back(LangOpts.WritableStrings);  // Allow writable strings
   Record.push_back(LangOpts.LaxVectorConversions);
@@ -610,7 +610,7 @@
                                   // may be ripped out at any time.
 
   Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
-  Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be 
+  Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
                                   // defined.
   Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
                                   // opposed to __DYNAMIC__).
@@ -641,15 +641,15 @@
 public:
   typedef const char * key_type;
   typedef key_type key_type_ref;
-  
+
   typedef std::pair<int, struct stat> data_type;
   typedef const data_type& data_type_ref;
 
   static unsigned ComputeHash(const char *path) {
     return BernsteinHash(path);
   }
-  
-  std::pair<unsigned,unsigned> 
+
+  std::pair<unsigned,unsigned>
     EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
                       data_type_ref Data) {
     unsigned StrLen = strlen(path);
@@ -660,19 +660,19 @@
     clang::io::Emit8(Out, DataLen);
     return std::make_pair(StrLen + 1, DataLen);
   }
-  
+
   void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
     Out.write(path, KeyLen);
   }
-  
+
   void EmitData(llvm::raw_ostream& Out, key_type_ref,
                 data_type_ref Data, unsigned DataLen) {
     using namespace clang::io;
     uint64_t Start = Out.tell(); (void)Start;
-    
+
     // Result of stat()
     Emit8(Out, Data.first? 1 : 0);
-    
+
     if (Data.first == 0) {
       Emit32(Out, (uint32_t) Data.second.st_ino);
       Emit32(Out, (uint32_t) Data.second.st_dev);
@@ -693,16 +693,16 @@
   // stat() call.
   OnDiskChainedHashTableGenerator<PCHStatCacheTrait> Generator;
   unsigned NumStatEntries = 0;
-  for (MemorizeStatCalls::iterator Stat = StatCalls.begin(), 
+  for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
                                 StatEnd = StatCalls.end();
        Stat != StatEnd; ++Stat, ++NumStatEntries) {
     const char *Filename = Stat->first();
     Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
     Generator.insert(Filename, Stat->second);
   }
-  
+
   // Create the on-disk hash table in a buffer.
-  llvm::SmallString<4096> StatCacheData; 
+  llvm::SmallString<4096> StatCacheData;
   uint32_t BucketOffset;
   {
     llvm::raw_svector_ostream Out(StatCacheData);
@@ -821,16 +821,16 @@
       if (FilenameLen)
         Record.insert(Record.end(), Filename, Filename + FilenameLen);
     }
-    
+
     // Emit the line entries
     for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
          L != LEnd; ++L) {
       // Emit the file ID
       Record.push_back(L->first);
-      
+
       // Emit the line entries
       Record.push_back(L->second.size());
-      for (std::vector<LineEntry>::iterator LE = L->second.begin(), 
+      for (std::vector<LineEntry>::iterator LE = L->second.begin(),
                                          LEEnd = L->second.end();
            LE != LEEnd; ++LE) {
         Record.push_back(LE->FileOffset);
@@ -844,9 +844,9 @@
   }
 
   // Write out entries for all of the header files we know about.
-  HeaderSearch &HS = PP.getHeaderSearchInfo();  
+  HeaderSearch &HS = PP.getHeaderSearchInfo();
   Record.clear();
-  for (HeaderSearch::header_file_iterator I = HS.header_file_begin(), 
+  for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
                                           E = HS.header_file_end();
        I != E; ++I) {
     Record.push_back(I->isImport);
@@ -862,7 +862,7 @@
   std::vector<uint32_t> SLocEntryOffsets;
   RecordData PreloadSLocs;
   SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1);
-  for (SourceManager::sloc_entry_iterator 
+  for (SourceManager::sloc_entry_iterator
          SLoc = SourceMgr.sloc_entry_begin() + 1,
          SLocEnd = SourceMgr.sloc_entry_end();
        SLoc != SLocEnd; ++SLoc) {
@@ -892,7 +892,7 @@
       if (Content->Entry) {
         // The source location entry is a file. The blob associated
         // with this entry is the file name.
-        
+
         // Turn the file name into an absolute path, if it isn't already.
         const char *Filename = Content->Entry->getName();
         llvm::sys::Path FilePath(Filename, strlen(Filename));
@@ -903,7 +903,7 @@
           FilenameStr = P.str();
           Filename = FilenameStr.c_str();
         }
-        
+
         Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
         Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename);
 
@@ -962,13 +962,13 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
   unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
-  
+
   Record.clear();
   Record.push_back(pch::SOURCE_LOCATION_OFFSETS);
   Record.push_back(SLocEntryOffsets.size());
   Record.push_back(SourceMgr.getNextOffset());
   Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
-                            (const char *)&SLocEntryOffsets.front(), 
+                            (const char *)&SLocEntryOffsets.front(),
                            SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0]));
 
   // Write the source location entry preloads array, telling the PCH
@@ -995,12 +995,12 @@
 
   // Enter the preprocessor block.
   Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
-  
+
   // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
   // FIXME: use diagnostics subsystem for localization etc.
   if (PP.SawDateOrTime())
     fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
-    
+
   // Loop over all the macro definitions that are live at the end of the file,
   // emitting each to the PP section.
   for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
@@ -1019,13 +1019,13 @@
     MacroOffsets[I->first] = Stream.GetCurrentBitNo();
     Record.push_back(MI->getDefinitionLoc().getRawEncoding());
     Record.push_back(MI->isUsed());
-    
+
     unsigned Code;
     if (MI->isObjectLike()) {
       Code = pch::PP_MACRO_OBJECT_LIKE;
     } else {
       Code = pch::PP_MACRO_FUNCTION_LIKE;
-      
+
       Record.push_back(MI->isC99Varargs());
       Record.push_back(MI->isGNUVarargs());
       Record.push_back(MI->getNumArgs());
@@ -1042,19 +1042,19 @@
       // tokens in it because they are created by the parser, and thus can't be
       // in a macro definition.
       const Token &Tok = MI->getReplacementToken(TokNo);
-      
+
       Record.push_back(Tok.getLocation().getRawEncoding());
       Record.push_back(Tok.getLength());
 
       // FIXME: When reading literal tokens, reconstruct the literal pointer if
       // it is needed.
       AddIdentifierRef(Tok.getIdentifierInfo(), Record);
-      
+
       // FIXME: Should translate token kind to a stable encoding.
       Record.push_back(Tok.getKind());
       // FIXME: Should translate token flags to a stable encoding.
       Record.push_back(Tok.getFlags());
-      
+
       Stream.EmitRecord(pch::PP_TOKEN, Record);
       Record.clear();
     }
@@ -1065,18 +1065,18 @@
 
 void PCHWriter::WriteComments(ASTContext &Context) {
   using namespace llvm;
-  
+
   if (Context.Comments.empty())
     return;
-  
+
   BitCodeAbbrev *CommentAbbrev = new BitCodeAbbrev();
   CommentAbbrev->Add(BitCodeAbbrevOp(pch::COMMENT_RANGES));
   CommentAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
   unsigned CommentCode = Stream.EmitAbbrev(CommentAbbrev);
-  
+
   RecordData Record;
   Record.push_back(pch::COMMENT_RANGES);
-  Stream.EmitRecordWithBlob(CommentCode, Record, 
+  Stream.EmitRecordWithBlob(CommentCode, Record,
                             (const char*)&Context.Comments[0],
                             Context.Comments.size() * sizeof(SourceRange));
 }
@@ -1090,7 +1090,7 @@
   pch::TypeID &ID = TypeIDs[T];
   if (ID == 0) // we haven't seen this type before.
     ID = NextTypeID++;
-  
+
   // Record the offset for this type.
   if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
     TypeOffsets.push_back(Stream.GetCurrentBitNo());
@@ -1100,7 +1100,7 @@
   }
 
   RecordData Record;
-  
+
   // Emit the type's representation.
   PCHTypeWriter W(*this, Record);
   switch (T->getTypeClass()) {
@@ -1154,7 +1154,7 @@
 ///
 /// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
 /// bistream, or 0 if no block was written.
-uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context, 
+uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
                                                  DeclContext *DC) {
   if (DC->decls_empty())
     return 0;
@@ -1206,7 +1206,7 @@
     AddDeclarationName(D->first, Record);
     DeclContext::lookup_result Result = D->second.getLookupResult(Context);
     Record.push_back(Result.second - Result.first);
-    for(; Result.first != Result.second; ++Result.first)
+    for (; Result.first != Result.second; ++Result.first)
       AddDeclRef(*Result.first, Record);
   }
 
@@ -1230,12 +1230,12 @@
 public:
   typedef Selector key_type;
   typedef key_type key_type_ref;
-  
+
   typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
   typedef const data_type& data_type_ref;
 
   explicit PCHMethodPoolTrait(PCHWriter &Writer) : Writer(Writer) { }
-  
+
   static unsigned ComputeHash(Selector Sel) {
     unsigned N = Sel.getNumArgs();
     if (N == 0)
@@ -1246,27 +1246,27 @@
         R = clang::BernsteinHashPartial(II->getName(), II->getLength(), R);
     return R;
   }
-  
-  std::pair<unsigned,unsigned> 
+
+  std::pair<unsigned,unsigned>
     EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel,
                       data_type_ref Methods) {
     unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
     clang::io::Emit16(Out, KeyLen);
     unsigned DataLen = 2 + 2; // 2 bytes for each of the method counts
-    for (const ObjCMethodList *Method = &Methods.first; Method; 
+    for (const ObjCMethodList *Method = &Methods.first; Method;
          Method = Method->Next)
       if (Method->Method)
         DataLen += 4;
-    for (const ObjCMethodList *Method = &Methods.second; Method; 
+    for (const ObjCMethodList *Method = &Methods.second; Method;
          Method = Method->Next)
       if (Method->Method)
         DataLen += 4;
     clang::io::Emit16(Out, DataLen);
     return std::make_pair(KeyLen, DataLen);
   }
-  
+
   void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) {
-    uint64_t Start = Out.tell(); 
+    uint64_t Start = Out.tell();
     assert((Start >> 32) == 0 && "Selector key offset too large");
     Writer.SetSelectorOffset(Sel, Start);
     unsigned N = Sel.getNumArgs();
@@ -1274,32 +1274,32 @@
     if (N == 0)
       N = 1;
     for (unsigned I = 0; I != N; ++I)
-      clang::io::Emit32(Out, 
+      clang::io::Emit32(Out,
                     Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
   }
-  
+
   void EmitData(llvm::raw_ostream& Out, key_type_ref,
                 data_type_ref Methods, unsigned DataLen) {
     uint64_t Start = Out.tell(); (void)Start;
     unsigned NumInstanceMethods = 0;
-    for (const ObjCMethodList *Method = &Methods.first; Method; 
+    for (const ObjCMethodList *Method = &Methods.first; Method;
          Method = Method->Next)
       if (Method->Method)
         ++NumInstanceMethods;
 
     unsigned NumFactoryMethods = 0;
-    for (const ObjCMethodList *Method = &Methods.second; Method; 
+    for (const ObjCMethodList *Method = &Methods.second; Method;
          Method = Method->Next)
       if (Method->Method)
         ++NumFactoryMethods;
 
     clang::io::Emit16(Out, NumInstanceMethods);
     clang::io::Emit16(Out, NumFactoryMethods);
-    for (const ObjCMethodList *Method = &Methods.first; Method; 
+    for (const ObjCMethodList *Method = &Methods.first; Method;
          Method = Method->Next)
       if (Method->Method)
         clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
-    for (const ObjCMethodList *Method = &Methods.second; Method; 
+    for (const ObjCMethodList *Method = &Methods.second; Method;
          Method = Method->Next)
       if (Method->Method)
         clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
@@ -1321,13 +1321,13 @@
   bool Empty = true;
   {
     OnDiskChainedHashTableGenerator<PCHMethodPoolTrait> Generator;
-    
+
     // Create the on-disk hash table representation. Start by
     // iterating through the instance method pool.
     PCHMethodPoolTrait::key_type Key;
     unsigned NumSelectorsInMethodPool = 0;
     for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
-           Instance = SemaRef.InstanceMethodPool.begin(), 
+           Instance = SemaRef.InstanceMethodPool.begin(),
            InstanceEnd = SemaRef.InstanceMethodPool.end();
          Instance != InstanceEnd; ++Instance) {
       // Check whether there is a factory method with the same
@@ -1337,7 +1337,7 @@
 
       if (Factory == SemaRef.FactoryMethodPool.end())
         Generator.insert(Instance->first,
-                         std::make_pair(Instance->second, 
+                         std::make_pair(Instance->second,
                                         ObjCMethodList()));
       else
         Generator.insert(Instance->first,
@@ -1350,7 +1350,7 @@
     // Now iterate through the factory method pool, to pick up any
     // selectors that weren't already in the instance method pool.
     for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
-           Factory = SemaRef.FactoryMethodPool.begin(), 
+           Factory = SemaRef.FactoryMethodPool.begin(),
            FactoryEnd = SemaRef.FactoryMethodPool.end();
          Factory != FactoryEnd; ++Factory) {
       // Check whether there is an instance method with the same
@@ -1371,7 +1371,7 @@
       return;
 
     // Create the on-disk hash table in a buffer.
-    llvm::SmallString<4096> MethodPool; 
+    llvm::SmallString<4096> MethodPool;
     uint32_t BucketOffset;
     SelectorOffsets.resize(SelVector.size());
     {
@@ -1444,25 +1444,25 @@
 public:
   typedef const IdentifierInfo* key_type;
   typedef key_type  key_type_ref;
-  
+
   typedef pch::IdentID data_type;
   typedef data_type data_type_ref;
-  
-  PCHIdentifierTableTrait(PCHWriter &Writer, Preprocessor &PP) 
+
+  PCHIdentifierTableTrait(PCHWriter &Writer, Preprocessor &PP)
     : Writer(Writer), PP(PP) { }
 
   static unsigned ComputeHash(const IdentifierInfo* II) {
     return clang::BernsteinHash(II->getName());
   }
-  
-  std::pair<unsigned,unsigned> 
-    EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II, 
+
+  std::pair<unsigned,unsigned>
+    EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II,
                       pch::IdentID ID) {
     unsigned KeyLen = strlen(II->getName()) + 1;
     unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
     if (isInterestingIdentifier(II)) {
       DataLen += 2; // 2 bytes for builtin ID, flags
-      if (II->hasMacroDefinition() && 
+      if (II->hasMacroDefinition() &&
           !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro())
         DataLen += 4;
       for (IdentifierResolver::iterator D = IdentifierResolver::begin(II),
@@ -1477,16 +1477,16 @@
     clang::io::Emit16(Out, KeyLen);
     return std::make_pair(KeyLen, DataLen);
   }
-  
-  void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II, 
+
+  void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II,
                unsigned KeyLen) {
     // Record the location of the key data.  This is used when generating
     // the mapping from persistent IDs to strings.
     Writer.SetIdentifierOffset(II, Out.tell());
     Out.write(II->getName(), KeyLen);
   }
-  
-  void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II, 
+
+  void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II,
                 pch::IdentID ID, unsigned) {
     if (!isInterestingIdentifier(II)) {
       clang::io::Emit32(Out, ID << 1);
@@ -1495,8 +1495,8 @@
 
     clang::io::Emit32(Out, (ID << 1) | 0x01);
     uint32_t Bits = 0;
-    bool hasMacroDefinition = 
-      II->hasMacroDefinition() && 
+    bool hasMacroDefinition =
+      II->hasMacroDefinition() &&
       !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro();
     Bits = (uint32_t)II->getObjCOrBuiltinID();
     Bits = (Bits << 1) | hasMacroDefinition;
@@ -1514,7 +1514,7 @@
     // "stat"), but IdentifierResolver::AddDeclToIdentifierChain()
     // adds declarations to the end of the list (so we need to see the
     // struct "status" before the function "status").
-    llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II), 
+    llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
                                         IdentifierResolver::end());
     for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
                                                       DEnd = Decls.rend();
@@ -1536,7 +1536,7 @@
   // strings.
   {
     OnDiskChainedHashTableGenerator<PCHIdentifierTableTrait> Generator;
-    
+
     // Look for any identifiers that were named while processing the
     // headers, but are otherwise not needed. We add these to the hash
     // table to enable checking of the predefines buffer in the case
@@ -1557,7 +1557,7 @@
     }
 
     // Create the on-disk hash table in a buffer.
-    llvm::SmallString<4096> IdentifierTable; 
+    llvm::SmallString<4096> IdentifierTable;
     uint32_t BucketOffset;
     {
       PCHIdentifierTableTrait Trait(*this, PP);
@@ -1617,7 +1617,7 @@
 
     case Attr::AlwaysInline:
       break;
-     
+
     case Attr::AnalyzerNoReturn:
       break;
 
@@ -1676,7 +1676,7 @@
       Record.push_back(Sentinel->getNullPos());
       break;
     }
-        
+
     case Attr::GNUInline:
     case Attr::IBOutletKind:
     case Attr::Malloc:
@@ -1706,14 +1706,14 @@
 
     case Attr::Packed:
       break;
-    
+
     case Attr::Pure:
       break;
 
     case Attr::Regparm:
       Record.push_back(cast<RegparmAttr>(Attr)->getNumParams());
       break;
-        
+
     case Attr::ReqdWorkGroupSize:
       Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim());
       Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim());
@@ -1733,7 +1733,7 @@
 
     case Attr::Visibility:
       // FIXME: stable encoding
-      Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility()); 
+      Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility());
       break;
 
     case Attr::WarnUnusedResult:
@@ -1765,8 +1765,8 @@
   SelectorOffsets[ID - 1] = Offset;
 }
 
-PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream) 
-  : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS), 
+PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
+  : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
     NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
     NumVisibleDeclContexts(0) { }
 
@@ -1782,7 +1782,7 @@
   Stream.Emit((unsigned)'P', 8);
   Stream.Emit((unsigned)'C', 8);
   Stream.Emit((unsigned)'H', 8);
-  
+
   WriteBlockInfoBlock();
 
   // The translation unit is the first declaration we'll emit.
@@ -1816,7 +1816,7 @@
   RecordData LocallyScopedExternalDecls;
   // FIXME: This is filling in the PCH file in densemap order which is
   // nondeterminstic!
-  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator 
+  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
          TD = SemaRef.LocallyScopedExternalDecls.begin(),
          TDEnd = SemaRef.LocallyScopedExternalDecls.end();
        TD != TDEnd; ++TD)
@@ -1836,10 +1836,10 @@
     WriteStatCache(*StatCalls, isysroot);
   WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
   WritePreprocessor(PP);
-  WriteComments(Context);  
+  WriteComments(Context);
   // Write the record of special types.
   Record.clear();
-  
+
   AddTypeRef(Context.getBuiltinVaListType(), Record);
   AddTypeRef(Context.getObjCIdType(), Record);
   AddTypeRef(Context.getObjCSelType(), Record);
@@ -1853,7 +1853,7 @@
   AddTypeRef(Context.ObjCIdRedefinitionType, Record);
   AddTypeRef(Context.ObjCClassRedefinitionType, Record);
   Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
-  
+
   // Keep writing types and declarations until all types and
   // declarations have been written.
   do {
@@ -1876,9 +1876,9 @@
   Record.push_back(pch::TYPE_OFFSET);
   Record.push_back(TypeOffsets.size());
   Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record,
-                            (const char *)&TypeOffsets.front(), 
+                            (const char *)&TypeOffsets.front(),
                             TypeOffsets.size() * sizeof(TypeOffsets[0]));
-  
+
   // Write the declaration offsets array
   Abbrev = new BitCodeAbbrev();
   Abbrev->Add(BitCodeAbbrevOp(pch::DECL_OFFSET));
@@ -1889,7 +1889,7 @@
   Record.push_back(pch::DECL_OFFSET);
   Record.push_back(DeclOffsets.size());
   Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record,
-                            (const char *)&DeclOffsets.front(), 
+                            (const char *)&DeclOffsets.front(),
                             DeclOffsets.size() * sizeof(DeclOffsets[0]));
 
   // Write the record containing external, unnamed definitions.
@@ -1902,13 +1902,13 @@
 
   // Write the record containing locally-scoped external definitions.
   if (!LocallyScopedExternalDecls.empty())
-    Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS, 
+    Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
                       LocallyScopedExternalDecls);
 
   // Write the record containing ext_vector type names.
   if (!ExtVectorDecls.empty())
     Stream.EmitRecord(pch::EXT_VECTOR_DECLS, ExtVectorDecls);
-  
+
   // Some simple statistics
   Record.clear();
   Record.push_back(NumStatements);
@@ -2032,7 +2032,7 @@
   }
 
   pch::DeclID &ID = DeclIDs[D];
-  if (ID == 0) { 
+  if (ID == 0) {
     // We haven't seen this declaration before. Give it a new ID and
     // enqueue it in the list of declarations to emit.
     ID = DeclIDs.size();
