diff options
Diffstat (limited to 'lib/Frontend/PCHWriter.cpp')
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 166 |
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 |