[PCH] Keep track of file-level declarations that are contained by files.

Introduce a FILE_SORTED_DECLS [de]serialization record that contains
a file sorted array of file-level DeclIDs in a PCH/Module.
The rationale is to allow "targeted" deserialization of decls inside
a range of a source file.

Cocoa PCH increased by 0.8%
Difference of creation time for Cocoa PCH is below the noise level.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143238 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 13cdd0e..1b95e92 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/DeclContextInternals.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1651,14 +1652,20 @@
     unsigned Index = ID - FirstDeclID;
 
     // Record the offset for this declaration
+    SourceLocation Loc = D->getLocation();
     if (DeclOffsets.size() == Index)
-      DeclOffsets.push_back(DeclOffset(D->getLocation(),
-                                       Stream.GetCurrentBitNo()));
+      DeclOffsets.push_back(DeclOffset(Loc, Stream.GetCurrentBitNo()));
     else if (DeclOffsets.size() < Index) {
       DeclOffsets.resize(Index+1);
-      DeclOffsets[Index].setLocation(D->getLocation());
+      DeclOffsets[Index].setLocation(Loc);
       DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
     }
+    
+    SourceManager &SM = Context.getSourceManager();
+    if (Loc.isValid() && SM.isLocalSourceLocation(Loc)) {
+      SourceLocation FileLoc = SM.getFileLoc(Loc);
+      associateDeclWithFile(D, ID, FileLoc);
+    }
   }
 
   // Build and emit a record for this declaration