forked from OSchip/llvm-project
Revampled Serialization Tester to serialize and deserialize out an entire ASTContext and top-level decls.
llvm-svn: 43773
This commit is contained in:
parent
e344bbbe84
commit
3a68de993a
|
@ -23,8 +23,8 @@
|
|||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Bitcode/Serialize.h"
|
||||
#include "llvm/Bitcode/Deserialize.h"
|
||||
#include "llvm/System/TimeValue.h"
|
||||
#include <stdio.h>
|
||||
#include <list>
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Driver code.
|
||||
|
@ -43,164 +43,213 @@ template<typename T> struct Janitor {
|
|||
|
||||
class SerializationTest : public ASTConsumer {
|
||||
ASTContext* Context;
|
||||
llvm::sys::Path Filename;
|
||||
std::vector<unsigned char>* Buffer;
|
||||
llvm::BitstreamWriter* OBStream;
|
||||
llvm::Serializer* serializer;
|
||||
std::list<Decl*> Decls;
|
||||
|
||||
enum { ContextBlock = 0x1, DeclBlock = 0x3 };
|
||||
|
||||
void DeserializeTest();
|
||||
public:
|
||||
|
||||
SerializationTest(llvm::sys::Path filename);
|
||||
SerializationTest() : Context(NULL) {};
|
||||
~SerializationTest();
|
||||
|
||||
virtual void Initialize(ASTContext& context, unsigned);
|
||||
virtual void HandleTopLevelDecl(Decl *D);
|
||||
virtual void Initialize(ASTContext& context, unsigned) {
|
||||
Context = &context;
|
||||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D) {
|
||||
Decls.push_back(D);
|
||||
}
|
||||
|
||||
private:
|
||||
void Serialize(llvm::sys::Path& Filename);
|
||||
void Deserialize(llvm::sys::Path& Filename);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
ASTConsumer* clang::CreateSerializationTest() {
|
||||
std::string ErrMsg;
|
||||
llvm::sys::Path Filename = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
|
||||
|
||||
if (Filename.isEmpty()) {
|
||||
llvm::cerr << "Error: " << ErrMsg << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Filename.appendComponent("test.ast");
|
||||
|
||||
if (Filename.makeUnique(true,&ErrMsg)) {
|
||||
llvm::cerr << "Error: " << ErrMsg << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new SerializationTest(Filename);
|
||||
return new SerializationTest();
|
||||
}
|
||||
|
||||
SerializationTest::SerializationTest(llvm::sys::Path filename)
|
||||
: Filename(filename), OBStream(NULL), serializer(NULL) {
|
||||
static void WritePreamble(llvm::BitstreamWriter& Stream) {
|
||||
Stream.Emit((unsigned)'B', 8);
|
||||
Stream.Emit((unsigned)'C', 8);
|
||||
Stream.Emit(0xC, 4);
|
||||
Stream.Emit(0xF, 4);
|
||||
Stream.Emit(0xE, 4);
|
||||
Stream.Emit(0x0, 4);
|
||||
}
|
||||
|
||||
static bool ReadPremable(llvm::BitstreamReader& Stream) {
|
||||
return Stream.Read(8) != 'B' ||
|
||||
Stream.Read(8) != 'C' ||
|
||||
Stream.Read(4) != 0xC ||
|
||||
Stream.Read(4) != 0xF ||
|
||||
Stream.Read(4) != 0xE ||
|
||||
Stream.Read(4) != 0x0;
|
||||
}
|
||||
|
||||
void SerializationTest::Serialize(llvm::sys::Path& Filename) {
|
||||
|
||||
// Reserve 256K for bitstream buffer.
|
||||
Buffer = new std::vector<unsigned char>();
|
||||
assert (Buffer && "Could not allocate buffer.");
|
||||
Buffer->reserve(256*1024);
|
||||
std::vector<unsigned char> Buffer;
|
||||
Buffer.reserve(256*1024);
|
||||
|
||||
// Open bitstream and write preamble.
|
||||
OBStream = new llvm::BitstreamWriter(*Buffer);
|
||||
assert (OBStream && "could not create bitstream for serialization");
|
||||
// Create bitstream and write preamble.
|
||||
llvm::BitstreamWriter Stream(Buffer);
|
||||
WritePreamble(Stream);
|
||||
|
||||
OBStream->Emit((unsigned)'B', 8);
|
||||
OBStream->Emit((unsigned)'C', 8);
|
||||
OBStream->Emit(0xC, 4);
|
||||
OBStream->Emit(0xF, 4);
|
||||
OBStream->Emit(0xE, 4);
|
||||
OBStream->Emit(0x0, 4);
|
||||
// Create serializer.
|
||||
llvm::Serializer Sezr(Stream);
|
||||
|
||||
// Open serializer.
|
||||
serializer = new llvm::Serializer(*OBStream,0);
|
||||
assert (serializer && "could not create serializer");
|
||||
}
|
||||
// ===---------------------------------------------------===/
|
||||
// Serialize the "Translation Unit" metadata.
|
||||
// ===---------------------------------------------------===/
|
||||
|
||||
Sezr.EnterBlock(ContextBlock);
|
||||
|
||||
void SerializationTest::Initialize(ASTContext& context, unsigned) {
|
||||
llvm::cerr << "[ " << TimeValue::now().toString() << " ] "
|
||||
<< "Faux-serializing: SourceManager et al.\n";
|
||||
// "Fake" emit the SourceManager.
|
||||
llvm::cerr << "Faux-serializing: SourceManager.\n";
|
||||
Sezr.EmitPtr(&Context->SourceMgr);
|
||||
|
||||
serializer->EnterBlock();
|
||||
// "Fake" emit the SourceManager, etc.
|
||||
Context = &context;
|
||||
serializer->EmitPtr(&context.SourceMgr);
|
||||
serializer->EmitPtr(&context.Target);
|
||||
serializer->EmitPtr(&context.Idents);
|
||||
serializer->EmitPtr(&context.Selectors);
|
||||
// "Fake" emit the Target.
|
||||
llvm::cerr << "Faux-serializing: Target.\n";
|
||||
Sezr.EmitPtr(&Context->Target);
|
||||
|
||||
llvm::cerr << "[ " << TimeValue::now().toString() << " ] "
|
||||
<< "Serializing: ASTContext.\n";
|
||||
// "Fake" emit Selectors.
|
||||
llvm::cerr << "Faux-serializing: Selectors.\n";
|
||||
Sezr.EmitPtr(&Context->Selectors);
|
||||
|
||||
// Emit the Identifier Table.
|
||||
llvm::cerr << "Serializing: IdentifierTable.\n";
|
||||
Sezr.EmitOwnedPtr(&Context->Idents);
|
||||
|
||||
serializer->EmitOwnedPtr(&context);
|
||||
serializer->ExitBlock();
|
||||
}
|
||||
// Emit the ASTContext.
|
||||
llvm::cerr << "Serializing: ASTContext.\n";
|
||||
Sezr.EmitOwnedPtr(Context);
|
||||
|
||||
void SerializationTest::HandleTopLevelDecl(Decl *D) {
|
||||
llvm::cerr << "[ " << TimeValue::now().toString() << " ] "
|
||||
<< "Serializing: Decl.\n";
|
||||
Sezr.ExitBlock();
|
||||
|
||||
serializer->EnterBlock();
|
||||
serializer->EmitOwnedPtr(D);
|
||||
serializer->ExitBlock();
|
||||
}
|
||||
// ===---------------------------------------------------===/
|
||||
// Serialize the top-level decls.
|
||||
// ===---------------------------------------------------===/
|
||||
|
||||
SerializationTest::~SerializationTest() {
|
||||
delete serializer;
|
||||
delete OBStream;
|
||||
Sezr.EnterBlock(DeclBlock);
|
||||
|
||||
for (std::list<Decl*>::iterator I=Decls.begin(), E=Decls.end(); I!=E; ++I) {
|
||||
llvm::cerr << "Serializing: Decl.\n";
|
||||
Sezr.EmitOwnedPtr(*I);
|
||||
}
|
||||
|
||||
Sezr.ExitBlock();
|
||||
|
||||
// ===---------------------------------------------------===/
|
||||
// Finalize serialization: write the bits to disk.
|
||||
// ===---------------------------------------------------===/
|
||||
|
||||
if (FILE *fp = fopen(Filename.c_str(),"wb")) {
|
||||
fwrite((char*)&Buffer->front(), sizeof(char), Buffer->size(), fp);
|
||||
delete Buffer;
|
||||
fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
|
||||
fclose(fp);
|
||||
}
|
||||
else {
|
||||
llvm::cerr << "Error: Cannot open " << Filename.c_str() << "\n";
|
||||
delete Buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::cerr << "[ " << TimeValue::now().toString() << " ] "
|
||||
<< "Commited bitstream to disk: " << Filename.c_str() << "\n";
|
||||
|
||||
DeserializeTest();
|
||||
llvm::cerr << "Commited bitstream to disk: " << Filename.c_str() << "\n";
|
||||
}
|
||||
|
||||
void SerializationTest::DeserializeTest() {
|
||||
|
||||
llvm::MemoryBuffer* MBuffer =
|
||||
llvm::MemoryBuffer::getFile(Filename.c_str(), strlen(Filename.c_str()));
|
||||
void SerializationTest::Deserialize(llvm::sys::Path& Filename) {
|
||||
|
||||
// Create the memory buffer that contains the contents of the file.
|
||||
|
||||
using llvm::MemoryBuffer;
|
||||
|
||||
MemoryBuffer* MBuffer = MemoryBuffer::getFile(Filename.c_str(),
|
||||
strlen(Filename.c_str()));
|
||||
|
||||
if(!MBuffer) {
|
||||
llvm::cerr << "ERROR: Cannot read file for deserialization.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Janitor<llvm::MemoryBuffer> AutoReleaseBuffer(MBuffer);
|
||||
// Create an "autocollector" object to release the memory buffer upon
|
||||
// termination of the current scope.
|
||||
Janitor<MemoryBuffer> AutoReleaseBuffer(MBuffer);
|
||||
|
||||
// Check if the file is of the proper length.
|
||||
if (MBuffer->getBufferSize() & 0x3) {
|
||||
llvm::cerr << "ERROR: AST file should be a multiple of 4 bytes in length.\n";
|
||||
llvm::cerr << "ERROR: AST file length should be a multiple of 4 bytes.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char *BufPtr = (unsigned char *)MBuffer->getBufferStart();
|
||||
llvm::BitstreamReader IBStream(BufPtr,BufPtr+MBuffer->getBufferSize());
|
||||
// Create the bitstream reader.
|
||||
unsigned char *BufPtr = (unsigned char *) MBuffer->getBufferStart();
|
||||
llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer->getBufferSize());
|
||||
|
||||
// Sniff for the signature.
|
||||
if (IBStream.Read(8) != 'B' ||
|
||||
IBStream.Read(8) != 'C' ||
|
||||
IBStream.Read(4) != 0xC ||
|
||||
IBStream.Read(4) != 0xF ||
|
||||
IBStream.Read(4) != 0xE ||
|
||||
IBStream.Read(4) != 0x0) {
|
||||
// Sniff for the signature in the bitcode file.
|
||||
if (!ReadPremable(Stream)) {
|
||||
llvm::cerr << "ERROR: Invalid AST-bitcode signature.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::Deserializer deserializer(IBStream);
|
||||
// Create the Dezr.
|
||||
llvm::Deserializer Dezr(Stream);
|
||||
|
||||
// ===---------------------------------------------------===/
|
||||
// Deserialize the "Translation Unit" metadata.
|
||||
// ===---------------------------------------------------===/
|
||||
|
||||
// "Fake" read the SourceManager, etc.
|
||||
llvm::cerr << "[ " << TimeValue::now().toString() << " ] "
|
||||
<< "Faux-Deserializing: SourceManager et al.\n";
|
||||
// "Fake" read the SourceManager.
|
||||
llvm::cerr << "Faux-Deserializing: SourceManager.\n";
|
||||
Dezr.RegisterPtr(&Context->SourceMgr);
|
||||
|
||||
deserializer.RegisterPtr(&Context->SourceMgr);
|
||||
deserializer.RegisterPtr(&Context->Target);
|
||||
deserializer.RegisterPtr(&Context->Idents);
|
||||
deserializer.RegisterPtr(&Context->Selectors);
|
||||
// "Fake" read the TargetInfo.
|
||||
llvm::cerr << "Faux-Deserializing: Target.\n";
|
||||
Dezr.RegisterPtr(&Context->Target);
|
||||
|
||||
llvm::cerr << "[ " << TimeValue::now().toString() << " ] "
|
||||
<< "Deserializing: ASTContext.\n";
|
||||
// "Fake" read the Selectors.
|
||||
llvm::cerr << "Faux-Deserializing: Selectors.\n";
|
||||
Dezr.RegisterPtr(&Context->Selectors);
|
||||
|
||||
// Deserialize the AST context.
|
||||
deserializer.ReadOwnedPtr<ASTContext>();
|
||||
// ASTContext* context =
|
||||
// Read the identifier table.
|
||||
llvm::cerr << "Deserializing: IdentifierTable\n";
|
||||
Dezr.ReadOwnedPtr<IdentifierTable>();
|
||||
|
||||
// Read the ASTContext.
|
||||
llvm::cerr << "Deserializing: ASTContext.\n";
|
||||
Dezr.ReadOwnedPtr<ASTContext>();
|
||||
|
||||
// Create a printer to "consume" our deserialized ASTS.
|
||||
ASTConsumer* Printer = CreateASTPrinter();
|
||||
Janitor<ASTConsumer> PrinterJanitor(Printer);
|
||||
|
||||
// The remaining objects in the file are top-level decls.
|
||||
while (!Dezr.AtEnd()) {
|
||||
llvm::cerr << "Deserializing: Decl.\n";
|
||||
Decl* decl = Dezr.ReadOwnedPtr<Decl>();
|
||||
Printer->HandleTopLevelDecl(decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SerializationTest::~SerializationTest() {
|
||||
|
||||
std::string ErrMsg;
|
||||
llvm::sys::Path Filename = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
|
||||
|
||||
if (Filename.isEmpty()) {
|
||||
llvm::cerr << "Error: " << ErrMsg << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Filename.appendComponent("test.ast");
|
||||
|
||||
if (Filename.makeUnique(true,&ErrMsg)) {
|
||||
llvm::cerr << "Error: " << ErrMsg << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Serialize(Filename);
|
||||
Deserialize(Filename);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue