Include the SourceManager's line table in the PCH file. We can now
properly cope with #line directives in PCH files.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68963 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index fa6ad6f..4998de3 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -18,6 +18,7 @@
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManagerInternals.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Bitcode/BitstreamReader.h"
@@ -191,6 +192,50 @@
   return true;
 }
 
+/// \brief Read the line table in the source manager block.
+/// \returns true if ther was an error.
+static bool ParseLineTable(SourceManager &SourceMgr, 
+                           llvm::SmallVectorImpl<uint64_t> &Record) {
+  unsigned Idx = 0;
+  LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+  // Parse the file names
+  for (unsigned I = 0, N = Record[Idx++]; I != N; ++I) {
+    // Extract the file name
+    unsigned FilenameLen = Record[Idx++];
+    std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
+    Idx += FilenameLen;
+    unsigned ID = LineTable.getLineTableFilenameID(Filename.c_str(), 
+                                                   Filename.size());
+    if (ID != I)
+      return Error("Filename ID mismatch in PCH line table");
+  }
+
+  // Parse the line entries
+  std::vector<LineEntry> Entries;
+  while (Idx < Record.size()) {
+    unsigned FID = Record[Idx++];
+
+    // Extract the line entries
+    unsigned NumEntries = Record[Idx++];
+    Entries.clear();
+    Entries.reserve(NumEntries);
+    for (unsigned I = 0; I != NumEntries; ++I) {
+      unsigned FileOffset = Record[Idx++];
+      unsigned LineNo = Record[Idx++];
+      int FilenameID = Record[Idx++];
+      SrcMgr::CharacteristicKind FileKind 
+        = (SrcMgr::CharacteristicKind)Record[Idx++];
+      unsigned IncludeOffset = Record[Idx++];
+      Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
+                                       FileKind, IncludeOffset));
+    }
+    LineTable.AddEntry(FID, Entries);
+  }
+
+  return false;
+}
+
 /// \brief Read the source manager block
 PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
   using namespace SrcMgr;
@@ -242,9 +287,12 @@
       const FileEntry *File 
         = PP.getFileManager().getFile(BlobStart, BlobStart + BlobLen);
       // FIXME: Error recovery if file cannot be found.
-      SourceMgr.createFileID(File,
-                             SourceLocation::getFromRawEncoding(Record[1]),
-                             (CharacteristicKind)Record[2]);
+      FileID ID = SourceMgr.createFileID(File,
+                                SourceLocation::getFromRawEncoding(Record[1]),
+                                         (CharacteristicKind)Record[2]);
+      if (Record[3])
+        const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(ID).getFile())
+          .setHasLineDirectives();
       break;
     }
 
@@ -278,6 +326,10 @@
       break;
     }
 
+    case pch::SM_LINE_TABLE: {
+      if (ParseLineTable(SourceMgr, Record))
+        return Failure;
+    }
     }
   }
 }