aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/PCHReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/PCHReader.cpp')
-rw-r--r--lib/Frontend/PCHReader.cpp58
1 files changed, 55 insertions, 3 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index fa6ad6f0a0..4998de371f 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 @@ bool PCHReader::CheckPredefinesBuffer(const char *PCHPredef,
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 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
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 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
break;
}
+ case pch::SM_LINE_TABLE: {
+ if (ParseLineTable(SourceMgr, Record))
+ return Failure;
+ }
}
}
}