aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/PCHWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/PCHWriter.cpp')
-rw-r--r--lib/Frontend/PCHWriter.cpp166
1 files changed, 98 insertions, 68 deletions
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index c8b6465999..d181013a37 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -353,7 +353,9 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(SELECTOR_OFFSETS);
RECORD(METHOD_POOL);
RECORD(PP_COUNTER_VALUE);
-
+ RECORD(SOURCE_LOCATION_OFFSETS);
+ RECORD(SOURCE_LOCATION_PRELOADS);
+
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
RECORD(SM_SLOC_FILE_ENTRY);
@@ -578,22 +580,79 @@ static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) {
/// the files in the AST.
void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP) {
+ RecordData Record;
+
// Enter the source manager block.
Stream.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
// Abbreviations for the various kinds of source-location entries.
- int SLocFileAbbrv = -1;
- int SLocBufferAbbrv = -1;
- int SLocBufferBlobAbbrv = -1;
- int SLocInstantiationAbbrv = -1;
+ int SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
+ int SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
+ int SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream);
+ int SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream);
+
+ // Write the line table.
+ if (SourceMgr.hasLineTable()) {
+ LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+ // Emit the file names
+ Record.push_back(LineTable.getNumFilenames());
+ for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
+ // Emit the file name
+ const char *Filename = LineTable.getFilename(I);
+ unsigned FilenameLen = Filename? strlen(Filename) : 0;
+ Record.push_back(FilenameLen);
+ 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(),
+ LEEnd = L->second.end();
+ LE != LEEnd; ++LE) {
+ Record.push_back(LE->FileOffset);
+ Record.push_back(LE->LineNo);
+ Record.push_back(LE->FilenameID);
+ Record.push_back((unsigned)LE->FileKind);
+ Record.push_back(LE->IncludeOffset);
+ }
+ Stream.EmitRecord(pch::SM_LINE_TABLE, Record);
+ }
+ }
+
+ // Write out entries for all of the header files we know about.
+ HeaderSearch &HS = PP.getHeaderSearchInfo();
+ Record.clear();
+ for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
+ E = HS.header_file_end();
+ I != E; ++I) {
+ Record.push_back(I->isImport);
+ Record.push_back(I->DirInfo);
+ Record.push_back(I->NumIncludes);
+ AddIdentifierRef(I->ControllingMacro, Record);
+ Stream.EmitRecord(pch::SM_HEADER_FILE_INFO, Record);
+ Record.clear();
+ }
// Write out the source location entry table. We skip the first
// entry, which is always the same dummy entry.
- RecordData Record;
+ std::vector<uint64_t> SLocEntryOffsets;
+ RecordData PreloadSLocs;
+ SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1);
for (SourceManager::sloc_entry_iterator
SLoc = SourceMgr.sloc_entry_begin() + 1,
SLocEnd = SourceMgr.sloc_entry_end();
SLoc != SLocEnd; ++SLoc) {
+ // Record the offset of this source-location entry.
+ SLocEntryOffsets.push_back(Stream.GetCurrentBitNo());
+
// Figure out which record code to use.
unsigned Code;
if (SLoc->isFile()) {
@@ -603,6 +662,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Code = pch::SM_SLOC_BUFFER_ENTRY;
} else
Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
+ Record.clear();
Record.push_back(Code);
Record.push_back(SLoc->getOffset());
@@ -616,18 +676,17 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
if (Content->Entry) {
// The source location entry is a file. The blob associated
// with this entry is the file name.
- if (SLocFileAbbrv == -1)
- SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
Stream.EmitRecordWithBlob(SLocFileAbbrv, Record,
Content->Entry->getName(),
strlen(Content->Entry->getName()));
+
+ // FIXME: For now, preload all file source locations, so that
+ // we get the appropriate File entries in the reader. This is
+ // a temporary measure.
+ PreloadSLocs.push_back(SLocEntryOffsets.size());
} else {
// The source location entry is a buffer. The blob associated
// with this entry contains the contents of the buffer.
- if (SLocBufferAbbrv == -1) {
- SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
- SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream);
- }
// We add one to the size so that we capture the trailing NULL
// that is required by llvm::MemoryBuffer::getMemBuffer (on
@@ -640,6 +699,9 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
Buffer->getBufferStart(),
Buffer->getBufferSize() + 1);
+
+ if (strcmp(Name, "<built-in>") == 0)
+ PreloadSLocs.push_back(SLocEntryOffsets.size());
}
} else {
// The source location entry is an instantiation.
@@ -654,68 +716,36 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
if (++NextSLoc != SLocEnd)
NextOffset = NextSLoc->getOffset();
Record.push_back(NextOffset - SLoc->getOffset() - 1);
-
- if (SLocInstantiationAbbrv == -1)
- SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream);
Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
}
-
- Record.clear();
}
- // Write the line table.
- if (SourceMgr.hasLineTable()) {
- LineTableInfo &LineTable = SourceMgr.getLineTable();
-
- // Emit the file names
- Record.push_back(LineTable.getNumFilenames());
- for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
- // Emit the file name
- const char *Filename = LineTable.getFilename(I);
- unsigned FilenameLen = Filename? strlen(Filename) : 0;
- Record.push_back(FilenameLen);
- 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(),
- LEEnd = L->second.end();
- LE != LEEnd; ++LE) {
- Record.push_back(LE->FileOffset);
- Record.push_back(LE->LineNo);
- Record.push_back(LE->FilenameID);
- Record.push_back((unsigned)LE->FileKind);
- Record.push_back(LE->IncludeOffset);
- }
- Stream.EmitRecord(pch::SM_LINE_TABLE, Record);
- }
- }
+ Stream.ExitBlock();
- // Loop over all the header files.
- HeaderSearch &HS = PP.getHeaderSearchInfo();
- for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
- E = HS.header_file_end();
- I != E; ++I) {
- Record.push_back(I->isImport);
- Record.push_back(I->DirInfo);
- Record.push_back(I->NumIncludes);
- if (I->ControllingMacro)
- AddIdentifierRef(I->ControllingMacro, Record);
- else
- Record.push_back(0);
- Stream.EmitRecord(pch::SM_HEADER_FILE_INFO, Record);
- Record.clear();
- }
+ if (SLocEntryOffsets.empty())
+ return;
- Stream.ExitBlock();
+ // Write the source-location offsets table into the PCH block. This
+ // table is used for lazily loading source-location information.
+ using namespace llvm;
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(pch::SOURCE_LOCATION_OFFSETS));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
+ 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(),
+ SLocEntryOffsets.size() * 8);
+
+ // Write the source location entry preloads array, telling the PCH
+ // reader which source locations entries it should load eagerly.
+ Stream.EmitRecord(pch::SOURCE_LOCATION_PRELOADS, PreloadSLocs);
}
/// \brief Writes the block containing the serialized form of the