summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-11-16 20:05:18 +0000
committerDouglas Gregor <dgregor@apple.com>2011-11-16 20:05:18 +0000
commit9dc3212f98f1b6605cc5b4af7d047d0a2a1334ce (patch)
treefa54710fef94dd0fb7dc2695d6fa9e7c7b834df7 /clang/lib/Serialization/ASTReader.cpp
parentde2ac70c0a37a6f34296f76b5b78704d7970f532 (diff)
downloadbcm5719-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.cpp51
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;
}
OpenPOWER on IntegriCloud