diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/SourceManager.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 51 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 20 |
3 files changed, 55 insertions, 17 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index ddb1f39d1d..cdaff2f008 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -580,6 +580,7 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile, assert(IR && "getOrCreateContentCache() cannot return NULL"); const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree); + const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true; } void SourceManager::overrideFileContents(const FileEntry *SourceFile, diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 8961974856..0b2a884f82 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1081,9 +1081,18 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) { return Failure; case SM_SLOC_FILE_ENTRY: { - std::string Filename(BlobStart, BlobStart + BlobLen); + if (Record.size() < 7) { + Error("source location entry is incorrect"); + return Failure; + } + + bool OverriddenBuffer = Record[6]; + + std::string OrigFilename(BlobStart, BlobStart + BlobLen); + std::string Filename = OrigFilename; MaybeAddSystemRootToFilename(Filename); - const FileEntry *File = FileMgr.getFile(Filename); + const FileEntry *File = FileMgr.getFile(Filename, /*OpenFile=*/false, + /*CacheFailure=*/!OverriddenBuffer); if (File == 0 && !OriginalDir.empty() && !CurrentDir.empty() && OriginalDir != CurrentDir) { std::string resolved = resolveFileRelativeToOriginalDir(Filename, @@ -1103,11 +1112,6 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) { return Failure; } - if (Record.size() < 6) { - Error("source location entry is incorrect"); - return Failure; - } - if (!DisableValidation && ((off_t)Record[4] != File->getSize() #if !defined(LLVM_ON_WIN32) @@ -1131,18 +1135,35 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) { ID, BaseOffset + Record[0]); SrcMgr::FileInfo &FileInfo = const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile()); - FileInfo.NumCreatedFIDs = Record[6]; + FileInfo.NumCreatedFIDs = Record[7]; if (Record[3]) FileInfo.setHasLineDirectives(); - const DeclID *FirstDecl = F->FileSortedDecls + Record[7]; - unsigned NumFileDecls = Record[8]; + const DeclID *FirstDecl = F->FileSortedDecls + Record[8]; + unsigned NumFileDecls = Record[9]; if (NumFileDecls) { assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl, NumFileDecls)); } + if (OverriddenBuffer && + !SourceMgr.getOrCreateContentCache(File)->BufferOverridden) { + unsigned Code = SLocEntryCursor.ReadCode(); + Record.clear(); + unsigned RecCode + = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen); + + if (RecCode != SM_SLOC_BUFFER_BLOB) { + Error("AST record has invalid code"); + return Failure; + } + + llvm::MemoryBuffer *Buffer + = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1), + Filename); + SourceMgr.overrideFileContents(File, Buffer); + } break; } @@ -1160,8 +1181,8 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) { } llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1), - Name); + = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1), + Name); FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, BaseOffset + Offset); @@ -2341,6 +2362,10 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(Module &M) { return Failure; case SM_SLOC_FILE_ENTRY: { + // If the buffer was overridden, the file need not exist. + if (Record[6]) + break; + StringRef Filename(BlobStart, BlobLen); const FileEntry *File = getFileEntry(Filename); @@ -2352,7 +2377,7 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(Module &M) { return IgnorePCH; } - if (Record.size() < 6) { + if (Record.size() < 7) { Error("source location entry is incorrect"); return Failure; } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 6893dbd9f5..51aadb35e5 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1174,6 +1174,7 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { // FileEntry fields. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // BufferOverridden Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls @@ -1421,7 +1422,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Figure out which record code to use. unsigned Code; if (SLoc->isFile()) { - if (SLoc->getFile().getContentCache()->OrigEntry) { + const SrcMgr::ContentCache *Cache = SLoc->getFile().getContentCache(); + if (Cache->OrigEntry) { Code = SM_SLOC_FILE_ENTRY; SLocFileEntryOffsets.push_back(Stream.GetCurrentBitNo()); } else @@ -1442,7 +1444,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, const SrcMgr::ContentCache *Content = File.getContentCache(); if (Content->OrigEntry) { assert(Content->OrigEntry == Content->ContentsEntry && - "Writing to AST an overriden file is not supported"); + "Writing to AST an overridden file is not supported"); // The source location entry is a file. The blob associated // with this entry is the file name. @@ -1450,7 +1452,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Emit size/modification time for this file. Record.push_back(Content->OrigEntry->getSize()); Record.push_back(Content->OrigEntry->getModificationTime()); - + Record.push_back(Content->BufferOverridden); Record.push_back(File.NumCreatedFIDs); FileDeclIDsTy::iterator FDI = FileDeclIDs.find(SLoc); @@ -1461,7 +1463,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(0); Record.push_back(0); } - + // Turn the file name into an absolute path, if it isn't already. const char *Filename = Content->OrigEntry->getName(); llvm::SmallString<128> FilePath(Filename); @@ -1477,6 +1479,16 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename); + + if (Content->BufferOverridden) { + Record.clear(); + Record.push_back(SM_SLOC_BUFFER_BLOB); + const llvm::MemoryBuffer *Buffer + = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); + Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, + StringRef(Buffer->getBufferStart(), + Buffer->getBufferSize() + 1)); + } } else { // The source location entry is a buffer. The blob associated // with this entry contains the contents of the buffer. |