diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-11-16 20:05:18 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-11-16 20:05:18 +0000 |
commit | 9dc3212f98f1b6605cc5b4af7d047d0a2a1334ce (patch) | |
tree | fa54710fef94dd0fb7dc2695d6fa9e7c7b834df7 /clang/lib/Serialization/ASTReader.cpp | |
parent | de2ac70c0a37a6f34296f76b5b78704d7970f532 (diff) | |
download | bcm5719-llvm-9dc3212f98f1b6605cc5b4af7d047d0a2a1334ce.tar.gz bcm5719-llvm-9dc3212f98f1b6605cc5b4af7d047d0a2a1334ce.zip |
Implement (de-)serialization of the buffer contents for an overridden
file in the source manager. This allows us to properly create and use
modules described by module map files without umbrella headers (or
with incompletely umbrella headers). More generally, we can actually
build a PCH file that makes use of file -> buffer remappings, which
could be useful in libclang in the future.
llvm-svn: 144830
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 8961974856b..0b2a884f82a 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/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; } |