diff options
-rw-r--r-- | include/clang/Basic/SourceManager.h | 9 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 3 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 51 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 20 | ||||
-rw-r--r-- | test/Modules/normal-module-map.cpp | 8 |
6 files changed, 70 insertions, 22 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 5555557b98..cfd0430e60 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -102,8 +102,15 @@ namespace SrcMgr { /// NumLines - The number of lines in this ContentCache. This is only valid /// if SourceLineCache is non-null. - unsigned NumLines; + unsigned NumLines : 31; + /// \brief Indicates whether the buffer itself was provided to override + /// the actual file contents. + /// + /// When true, the original entry may be a virtual file that does not + /// exist. + unsigned BufferOverridden : 1; + /// getBuffer - Returns the memory buffer for the associated content. /// /// \param Diag Object through which diagnostics will be emitted if the diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index e3a1020123..53d970b684 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -452,7 +452,8 @@ namespace clang { SM_SLOC_BUFFER_ENTRY = 2, /// \brief Describes a blob that contains the data for a buffer /// entry. This kind of record always directly follows a - /// SM_SLOC_BUFFER_ENTRY record. + /// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an + /// overridden buffer. SM_SLOC_BUFFER_BLOB = 3, /// \brief Describes a source location entry (SLocEntry) for a /// macro expansion. 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. diff --git a/test/Modules/normal-module-map.cpp b/test/Modules/normal-module-map.cpp index 9e9f31578d..c8338b7061 100644 --- a/test/Modules/normal-module-map.cpp +++ b/test/Modules/normal-module-map.cpp @@ -1,4 +1,8 @@ // RUN: rm -rf %t +// FIXME: Eventually, we should be able to remove these explicit module creation lines +// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libA -emit-module-from-map %S/Inputs/normal-module-map/module.map +// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libB -emit-module-from-map %S/Inputs/normal-module-map/module.map +// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fmodule-name=libNested -emit-module-from-map %S/Inputs/normal-module-map/nested/module.map // RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fauto-module-import -I %S/Inputs/normal-module-map %s -verify #include "Umbrella/Umbrella.h" @@ -8,9 +12,7 @@ int getUmbrella() { __import_module__ Umbrella2; -// FIXME: The expected error here is temporary, since we don't yet have the -// logic to build a module from a module map. -#include "a1.h" // expected-error{{module 'libA' not found}} +#include "a1.h" #include "b1.h" #include "nested/nested2.h" |