diff options
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3e153327923..985bcb05b4d 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -50,6 +50,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Support/Compression.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -962,6 +963,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(SM_SLOC_FILE_ENTRY); RECORD(SM_SLOC_BUFFER_ENTRY); RECORD(SM_SLOC_BUFFER_BLOB); + RECORD(SM_SLOC_BUFFER_BLOB_COMPRESSED); RECORD(SM_SLOC_EXPANSION_ENTRY); // Preprocessor Block. @@ -1631,11 +1633,15 @@ static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { /// \brief Create an abbreviation for the SLocEntry that refers to a /// buffer's blob. -static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) { +static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream, + bool Compressed) { using namespace llvm; auto *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_BLOB)); + Abbrev->Add(BitCodeAbbrevOp(Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED + : SM_SLOC_BUFFER_BLOB)); + if (Compressed) + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Uncompressed size Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob return Stream.EmitAbbrev(Abbrev); } @@ -1857,12 +1863,14 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, RecordData Record; // Enter the source manager block. - Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 3); + Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 4); // Abbreviations for the various kinds of source-location entries. unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream); unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream); - unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream); + unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream, false); + unsigned SLocBufferBlobCompressedAbbrv = + CreateSLocBufferBlobAbbrev(Stream, true); unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream); // Write out the source location entry table. We skip the first @@ -1902,6 +1910,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(File.hasLineDirectives()); const SrcMgr::ContentCache *Content = File.getContentCache(); + bool EmitBlob = false; if (Content->OrigEntry) { assert(Content->OrigEntry == Content->ContentsEntry && "Writing to AST an overridden file is not supported"); @@ -1923,14 +1932,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Stream.EmitRecordWithAbbrev(SLocFileAbbrv, Record); - if (Content->BufferOverridden || Content->IsTransient) { - RecordData::value_type Record[] = {SM_SLOC_BUFFER_BLOB}; - const llvm::MemoryBuffer *Buffer - = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); - Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, - StringRef(Buffer->getBufferStart(), - Buffer->getBufferSize() + 1)); - } + if (Content->BufferOverridden || Content->IsTransient) + EmitBlob = true; } else { // The source location entry is a buffer. The blob associated // with this entry contains the contents of the buffer. @@ -1943,15 +1946,34 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, const char *Name = Buffer->getBufferIdentifier(); Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record, StringRef(Name, strlen(Name) + 1)); - RecordData::value_type Record[] = {SM_SLOC_BUFFER_BLOB}; - Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, - StringRef(Buffer->getBufferStart(), - Buffer->getBufferSize() + 1)); + EmitBlob = true; if (strcmp(Name, "<built-in>") == 0) { PreloadSLocs.push_back(SLocEntryOffsets.size()); } } + + if (EmitBlob) { + // Include the implicit terminating null character in the on-disk buffer + // if we're writing it uncompressed. + const llvm::MemoryBuffer *Buffer = + Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager()); + StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1); + + // Compress the buffer if possible. We expect that almost all PCM + // consumers will not want its contents. + SmallString<0> CompressedBuffer; + if (llvm::zlib::compress(Blob.drop_back(1), CompressedBuffer) == + llvm::zlib::StatusOK) { + RecordData::value_type Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, + Blob.size() - 1}; + Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record, + CompressedBuffer); + } else { + RecordData::value_type Record[] = {SM_SLOC_BUFFER_BLOB}; + Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob); + } + } } else { // The source location entry is a macro expansion. const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion(); |