Implemented initial serialization support for SourceManager.

llvm-svn: 44590
This commit is contained in:
Ted Kremenek 2007-12-05 00:14:18 +00:00
parent ca0cb926f4
commit 57f4c00241
2 changed files with 149 additions and 46 deletions

View File

@ -410,53 +410,135 @@ void SourceManager::PrintStats() const {
//===----------------------------------------------------------------------===//
// Serialization.
//===----------------------------------------------------------------------===//
void SrcMgr::ContentCache::Emit(llvm::Serializer& S,
bool StoreBufferName,
bool StoreBufferContents) const {
void ContentCache::Emit(llvm::Serializer& S) const {
S.FlushRecord();
S.EmitPtr(this);
if (StoreBufferName)
S.EmitCStr(Buffer->getBufferIdentifier());
if (StoreBufferContents) {
// Emit the contents of the memory buffer.
// FIXME: use abbreviations to optimize this.
S.FlushRecord();
if (Entry) S.EmitCStr(Buffer->getBufferIdentifier());
else {
const char* p = Buffer->getBufferStart();
const char* e = Buffer->getBufferEnd();
S.EmitInt(p-e);
S.EmitInt(e-p);
for ( ; p != e; ++p)
S.EmitInt(*p);
S.FlushRecord();
}
}
void SrcMgr::ContentCache::Read(llvm::Deserializer& D,
std::vector<char>* BufferNameBuf,
bool ReadBufferContents) {
D.RegisterPtr(this);
const char* BufferName = "";
if (BufferNameBuf) {
D.ReadCStr(*BufferNameBuf);
BufferName = &(*BufferNameBuf)[0];
S.EmitInt(*p);
}
if (ReadBufferContents) {
char *BufferName = D.ReadCStr();
unsigned Size = D.ReadInt();
Buffer = MemoryBuffer::getNewUninitMemBuffer(Size,BufferName);
char* p = const_cast<char*>(Buffer->getBufferStart());
const char* e = Buffer->getBufferEnd();
for ( ; p != e ; ++p )
*p = (char) D.ReadInt();
}
else
Buffer = MemoryBuffer::getNewUninitMemBuffer(0,BufferName);
S.FlushRecord();
}
void ContentCache::ReadToSourceManager(llvm::Deserializer& D,
SourceManager& SMgr,
FileManager* FMgr,
std::vector<char>& Buf) {
if (FMgr) {
llvm::SerializedPtrID PtrID = D.ReadPtrID();
D.ReadCStr(Buf,false);
// Create/fetch the FileEntry.
const char* start = &Buf[0];
const FileEntry* E = FMgr->getFile(start,start+Buf.size());
assert (E && "Not yet supported: missing files.");
// Get the ContextCache object and register it with the deserializer.
D.RegisterPtr(PtrID,SMgr.getContentCache(E));
}
else {
// Register the ContextCache object with the deserializer.
SMgr.MemBufferInfos.push_back(ContentCache());
ContentCache& Entry = const_cast<ContentCache&>(SMgr.MemBufferInfos.back());
D.RegisterPtr(&Entry);
// Create the buffer.
unsigned Size = D.ReadInt();
Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size);
// Read the contents of the buffer.
char* p = const_cast<char*>(Entry.Buffer->getBufferStart());
for (unsigned i = 0; i < Size ; ++i)
p[i] = D.ReadInt();
}
}
void FileIDInfo::Emit(llvm::Serializer& S) const {
S.Emit(IncludeLoc);
S.EmitInt(ChunkNo);
S.EmitPtr(Content);
}
FileIDInfo FileIDInfo::ReadVal(llvm::Deserializer& D) {
FileIDInfo I;
I.IncludeLoc = SourceLocation::ReadVal(D);
I.ChunkNo = D.ReadInt();
D.ReadPtr(I.Content,false);
return I;
}
void MacroIDInfo::Emit(llvm::Serializer& S) const {
S.Emit(VirtualLoc);
S.Emit(PhysicalLoc);
}
MacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) {
MacroIDInfo I;
I.VirtualLoc = SourceLocation::ReadVal(D);
I.PhysicalLoc = SourceLocation::ReadVal(D);
return I;
}
void SourceManager::Emit(llvm::Serializer& S) const {
// Emit: FileInfos. Just emit the file name.
S.EnterBlock();
std::for_each(FileInfos.begin(),FileInfos.end(),
S.MakeEmitter<ContentCache>());
S.ExitBlock();
// Emit: MemBufferInfos
S.EnterBlock();
std::for_each(MemBufferInfos.begin(), MemBufferInfos.end(),
S.MakeEmitter<ContentCache>());
S.ExitBlock();
// Emit: FileIDs
S.EmitInt(FileIDs.size());
std::for_each(FileIDs.begin(), FileIDs.end(), S.MakeEmitter<FileIDInfo>());
// Emit: MacroIDs
S.EmitInt(MacroIDs.size());
std::for_each(MacroIDs.begin(), MacroIDs.end(), S.MakeEmitter<MacroIDInfo>());
}
void SourceManager::Read(llvm::Deserializer& D, FileManager& FMgr) {
std::vector<char> Buf;
{ // Read: FileInfos.
llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
while (!D.FinishedBlock(BLoc))
ContentCache::ReadToSourceManager(D,*this,&FMgr,Buf);
}
{ // Read: MemBufferInfos.
llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
while (!D.FinishedBlock(BLoc))
ContentCache::ReadToSourceManager(D,*this,NULL,Buf);
}
// Read: FileIDs.
unsigned Size = D.ReadInt();
FileIDs.reserve(Size);
for (; Size > 0 ; --Size)
FileIDs.push_back(FileIDInfo::ReadVal(D));
// Read: MacroIDs.
Size = D.ReadInt();
MacroIDs.reserve(Size);
for (; Size > 0 ; --Size)
MacroIDs.push_back(MacroIDInfo::ReadVal(D));
}

View File

@ -28,6 +28,7 @@ class MemoryBuffer;
namespace clang {
class SourceManager;
class FileManager;
class FileEntry;
class IdentifierTokenInfo;
@ -72,13 +73,13 @@ namespace SrcMgr {
}
/// Emit - Emit this ContentCache to Bitcode.
void Emit(llvm::Serializer& S, bool StoreBufferName,
bool StoreBufferContents) const;
void Emit(llvm::Serializer& S) const;
/// ReadToSourceManager - Reconstitute a ContentCache from Bitcode
// and store it in the specified SourceManager.
static void ReadToSourceManager(llvm::Deserializer& D, SourceManager& SMgr,
FileManager* FMgr, std::vector<char>& Buf);
/// Read - Reconstitute a ContentCache from Bitcode.
void Read(llvm::Deserializer& D, std::vector<char>* BufferNameBuf,
bool ReadBufferContents);
private:
// Disable assignments.
ContentCache& operator=(const ContentCache& RHS);
@ -130,6 +131,12 @@ namespace SrcMgr {
SourceLocation getIncludeLoc() const { return IncludeLoc; }
unsigned getChunkNo() const { return ChunkNo; }
const ContentCache* getContentCache() const { return Content; }
/// Emit - Emit this FileIDInfo to Bitcode.
void Emit(llvm::Serializer& S) const;
/// ReadVal - Reconstitute a FileIDInfo from Bitcode.
static FileIDInfo ReadVal(llvm::Deserializer& S);
};
/// MacroIDInfo - Macro SourceLocations refer to these records by their ID.
@ -153,6 +160,12 @@ namespace SrcMgr {
X.PhysicalLoc = PL;
return X;
}
/// Emit - Emit this MacroIDInfo to Bitcode.
void Emit(llvm::Serializer& S) const;
/// ReadVal - Reconstitute a MacroIDInfo from Bitcode.
static MacroIDInfo ReadVal(llvm::Deserializer& S);
};
} // end SrcMgr namespace.
} // end clang namespace
@ -349,7 +362,15 @@ public:
///
void PrintStats() const;
/// Emit - Emit this SourceManager to Bitcode.
void Emit(llvm::Serializer& S) const;
/// Read - Reconstitute a SourceManager from Bitcode.
void Read(llvm::Deserializer& S, FileManager &FMgr);
private:
friend class SrcMgr::ContentCache; // Used for deserialization.
/// createFileID - Create a new fileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.