summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp53
1 files changed, 32 insertions, 21 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index dbfc5c31db1..1c62b4e57b0 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -48,6 +48,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -1203,6 +1204,32 @@ bool ASTReader::ReadSLocEntry(int ID) {
return true;
}
+ // Local helper to read the (possibly-compressed) buffer data following the
+ // entry record.
+ auto ReadBuffer = [this](
+ BitstreamCursor &SLocEntryCursor,
+ StringRef Name) -> std::unique_ptr<llvm::MemoryBuffer> {
+ RecordData Record;
+ StringRef Blob;
+ unsigned Code = SLocEntryCursor.ReadCode();
+ unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob);
+
+ if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
+ SmallString<0> Uncompressed;
+ if (llvm::zlib::uncompress(Blob, Uncompressed, Record[0]) !=
+ llvm::zlib::StatusOK) {
+ Error("could not decompress embedded file contents");
+ return nullptr;
+ }
+ return llvm::MemoryBuffer::getMemBufferCopy(Uncompressed, Name);
+ } else if (RecCode == SM_SLOC_BUFFER_BLOB) {
+ return llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name, true);
+ } else {
+ Error("AST record has invalid code");
+ return nullptr;
+ }
+ };
+
ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second;
F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);
BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
@@ -1258,24 +1285,16 @@ bool ASTReader::ReadSLocEntry(int ID) {
FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl,
NumFileDecls));
}
-
+
const SrcMgr::ContentCache *ContentCache
= SourceMgr.getOrCreateContentCache(File,
/*isSystemFile=*/FileCharacter != SrcMgr::C_User);
if (OverriddenBuffer && !ContentCache->BufferOverridden &&
ContentCache->ContentsEntry == ContentCache->OrigEntry &&
!ContentCache->getRawBuffer()) {
- unsigned Code = SLocEntryCursor.ReadCode();
- Record.clear();
- unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob);
-
- if (RecCode != SM_SLOC_BUFFER_BLOB) {
- Error("AST record has invalid code");
+ auto Buffer = ReadBuffer(SLocEntryCursor, File->getName());
+ if (!Buffer)
return true;
- }
-
- std::unique_ptr<llvm::MemoryBuffer> Buffer
- = llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), File->getName());
SourceMgr.overrideFileContents(File, std::move(Buffer));
}
@@ -1292,18 +1311,10 @@ bool ASTReader::ReadSLocEntry(int ID) {
(F->Kind == MK_ImplicitModule || F->Kind == MK_ExplicitModule)) {
IncludeLoc = getImportLocation(F);
}
- unsigned Code = SLocEntryCursor.ReadCode();
- Record.clear();
- unsigned RecCode
- = SLocEntryCursor.readRecord(Code, Record, &Blob);
- if (RecCode != SM_SLOC_BUFFER_BLOB) {
- Error("AST record has invalid code");
+ auto Buffer = ReadBuffer(SLocEntryCursor, Name);
+ if (!Buffer)
return true;
- }
-
- std::unique_ptr<llvm::MemoryBuffer> Buffer =
- llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name);
SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID,
BaseOffset + Offset, IncludeLoc);
break;
OpenPOWER on IntegriCloud