diff options
author | Ted Kremenek <kremenek@apple.com> | 2007-12-05 22:08:43 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2007-12-05 22:08:43 +0000 |
commit | 355376630641304f5edd04862ca7a721fe0f0782 (patch) | |
tree | cb80562f24c7d8ac34e9710793c764221b1925a8 /Driver/SerializationTest.cpp | |
parent | b26d71348ace5e02da0c58112f8c40da3a94d187 (diff) |
Converted SerializationTest (--test-pickling) to use the new TranslationUnit
class to serialize and deserialize translation units.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44634 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/SerializationTest.cpp')
-rw-r--r-- | Driver/SerializationTest.cpp | 308 |
1 files changed, 42 insertions, 266 deletions
diff --git a/Driver/SerializationTest.cpp b/Driver/SerializationTest.cpp index 813aa7ea7b..7bd6cd1313 100644 --- a/Driver/SerializationTest.cpp +++ b/Driver/SerializationTest.cpp @@ -14,72 +14,44 @@ // //===----------------------------------------------------------------------===// -#include "ASTConsumers.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/SourceManager.h" -#include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" #include "clang/AST/CFG.h" #include "clang.h" -#include "llvm/System/Path.h" -#include "llvm/Support/Streams.h" +#include "ASTConsumers.h" +#include "TranslationUnit.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Bitcode/Serialize.h" -#include "llvm/Bitcode/Deserialize.h" +#include "llvm/ADT/scoped_ptr.h" +#include "llvm/Support/Streams.h" #include <fstream> -#include <stdio.h> -#include <list> using namespace clang; //===----------------------------------------------------------------------===// -// Utility classes +// Driver code. //===----------------------------------------------------------------------===// namespace { - -template<typename T> class Janitor { - T* Obj; -public: - explicit Janitor(T* obj) : Obj(obj) {} - ~Janitor() { delete Obj; } - operator T*() const { return Obj; } - T* operator->() { return Obj; } -}; -//===----------------------------------------------------------------------===// -// Driver code. -//===----------------------------------------------------------------------===// - class SerializationTest : public ASTConsumer { - ASTContext* Context; + TranslationUnit TU; Diagnostic &Diags; - FileManager &FMgr; - const LangOptions& LangOpts; - std::list<Decl*> Decls; - - enum { BasicMetadataBlock = 1, - ASTContextBlock = 2, - DeclsBlock = 3 }; - + FileManager &FMgr; public: SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts) - : Context(NULL), Diags(d), FMgr(fmgr), LangOpts(LOpts) {}; + : TU(LOpts), Diags(d), FMgr(fmgr) {} ~SerializationTest(); virtual void Initialize(ASTContext& context, unsigned) { - Context = &context; - } - + TU.setContext(&context); + } + virtual void HandleTopLevelDecl(Decl *D) { - Decls.push_back(D); + TU.AddTopLevelDecl(D); } - private: - void Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint); - void Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint); + bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint); + bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint); }; } // end anonymous namespace @@ -90,241 +62,43 @@ clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr, return new SerializationTest(Diags,FMgr,LOpts); } -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 ReadPreamble(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, +bool SerializationTest::Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint) { - - // Reserve 256K for bitstream buffer. - std::vector<unsigned char> Buffer; - Buffer.reserve(256*1024); - - // Create bitstream and write preamble. - llvm::BitstreamWriter Stream(Buffer); - WritePreamble(Stream); - - // Create serializer. - llvm::Serializer Sezr(Stream); - - // ===---------------------------------------------------===/ - // Serialize the top-level decls. - // ===---------------------------------------------------===/ - - Sezr.EnterBlock(DeclsBlock); - - { // Create a printer to "consume" our deserialized ASTS. - - Janitor<ASTConsumer> Printer(CreateASTPrinter()); + { + // Pretty-print the decls to a temp file. std::ofstream DeclPP(FNameDeclPrint.c_str()); assert (DeclPP && "Could not open file for printing out decls."); - Janitor<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); + llvm::scoped_ptr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); - for (std::list<Decl*>::iterator I=Decls.begin(), E=Decls.end(); I!=E; ++I) { - llvm::cerr << "Serializing: Decl.\n"; - - // Only serialize the head of a decl chain. The ASTConsumer interfaces - // provides us with each top-level decl, including those nested in - // a decl chain, so we may be passed decls that are already serialized. - if (!Sezr.isRegistered(*I)) { - Printer->HandleTopLevelDecl(*I); - FilePrinter->HandleTopLevelDecl(*I); - - if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*I)) - if (FD->getBody()) { - // Construct and print a CFG. - Janitor<CFG> cfg(CFG::buildCFG(FD->getBody())); - cfg->print(DeclPP); - } - - // Serialize the decl. - Sezr.EmitOwnedPtr(*I); - } - } - } - - Sezr.ExitBlock(); - - // ===---------------------------------------------------===/ - // Serialize the "Translation Unit" metadata. - // ===---------------------------------------------------===/ - - // Emit ASTContext. - Sezr.EnterBlock(ASTContextBlock); - llvm::cerr << "Serializing: ASTContext.\n"; - Sezr.EmitOwnedPtr(Context); - Sezr.ExitBlock(); - - - Sezr.EnterBlock(BasicMetadataBlock); - - // Block for SourceManager and Target. Allows easy skipping around - // to the Selectors during deserialization. - Sezr.EnterBlock(); - - // "Fake" emit the SourceManager. - llvm::cerr << "Serializing: SourceManager.\n"; - Sezr.Emit(Context->SourceMgr); - - // Emit the Target. - llvm::cerr << "Serializing: Target.\n"; - Sezr.EmitPtr(&Context->Target); - Sezr.EmitCStr(Context->Target.getTargetTriple()); - - Sezr.ExitBlock(); - - // Emit the Selectors. - llvm::cerr << "Serializing: Selectors.\n"; - Sezr.Emit(Context->Selectors); - - // Emit the Identifier Table. - llvm::cerr << "Serializing: IdentifierTable.\n"; - Sezr.Emit(Context->Idents); - - 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); - fclose(fp); - } - else { - llvm::cerr << "Error: Cannot open " << Filename.c_str() << "\n"; - return; + for (TranslationUnit::iterator I=TU.begin(), E=TU.end(); I!=E; ++I) + FilePrinter->HandleTopLevelDecl(*I); } - llvm::cerr << "Commited bitstream to disk: " << Filename.c_str() << "\n"; + // Serialize the translation unit. + return TU.EmitBitcodeFile(Filename); } - -void SerializationTest::Deserialize(llvm::sys::Path& Filename, +bool SerializationTest::Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint) { - // Create the memory buffer that contains the contents of the file. - - using llvm::MemoryBuffer; - - Janitor<MemoryBuffer> MBuffer(MemoryBuffer::getFile(Filename.c_str(), - strlen(Filename.c_str()))); - - if(!MBuffer) { - llvm::cerr << "ERROR: Cannot read file for deserialization.\n"; - return; - } - - // Check if the file is of the proper length. - if (MBuffer->getBufferSize() & 0x3) { - llvm::cerr << "ERROR: AST file length should be a multiple of 4 bytes.\n"; - return; - } - - // Create the bitstream reader. - unsigned char *BufPtr = (unsigned char *) MBuffer->getBufferStart(); - llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer->getBufferSize()); - - // Sniff for the signature in the bitcode file. - if (ReadPreamble(Stream)) { - llvm::cerr << "ERROR: Invalid AST-bitcode signature.\n"; - return; - } - - // Create the deserializer. - llvm::Deserializer Dezr(Stream); - - // ===---------------------------------------------------===/ - // Deserialize the "Translation Unit" metadata. - // ===---------------------------------------------------===/ - - // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock - // (which will appear earlier) and record its location. - - bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock); - assert (FoundBlock); + // Deserialize the translation unit. + TranslationUnit* NewTU = TranslationUnit::ReadBitcodeFile(Filename,FMgr); - llvm::Deserializer::Location ASTContextBlockLoc = - Dezr.getCurrentBlockLocation(); + if (!NewTU) + return false; - FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock); - assert (FoundBlock); - - // Read the SourceManager. - llvm::cerr << "Deserializing: SourceManager.\n"; - SourceManager::CreateAndRegister(Dezr,FMgr); - - { // Read the TargetInfo. - llvm::cerr << "Deserializing: Target.\n"; - llvm::SerializedPtrID PtrID = Dezr.ReadPtrID(); - char* triple = Dezr.ReadCStr(NULL,0,true); - std::vector<std::string> triples; - triples.push_back(triple); - delete [] triple; - Dezr.RegisterPtr(PtrID,CreateTargetInfo(triples,&Diags)); - } - - // For Selectors, we must read the identifier table first because the - // SelectorTable depends on the identifiers being already deserialized. - llvm::Deserializer::Location SelectorBlockLoc = - Dezr.getCurrentBlockLocation(); - - Dezr.SkipBlock(); - - // Read the identifier table. - llvm::cerr << "Deserializing: IdentifierTable\n"; - IdentifierTable::CreateAndRegister(Dezr); - - // Now jump back and read the selectors. - llvm::cerr << "Deserializing: Selectors\n"; - Dezr.JumpTo(SelectorBlockLoc); - SelectorTable::CreateAndRegister(Dezr); - - // Now jump back to ASTContextBlock and read the ASTContext. - llvm::cerr << "Deserializing: ASTContext.\n"; - Dezr.JumpTo(ASTContextBlockLoc); - Dezr.ReadOwnedPtr<ASTContext>(); - - // "Rewind" the stream. Find the block with the serialized top-level decls. - Dezr.Rewind(); - FoundBlock = Dezr.SkipToBlock(DeclsBlock); - assert (FoundBlock); - llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation(); - - // Create a printer to "consume" our deserialized ASTS. - ASTConsumer* Printer = CreateASTPrinter(); - Janitor<ASTConsumer> PrinterJanitor(Printer); - std::ofstream DeclPP(FNameDeclPrint.c_str()); - assert (DeclPP && "Could not open file for printing out decls."); - Janitor<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); - - // The remaining objects in the file are top-level decls. - while (!Dezr.FinishedBlock(DeclBlockLoc)) { - llvm::cerr << "Deserializing: Decl.\n"; - Decl* decl = Dezr.ReadOwnedPtr<Decl>(); - Printer->HandleTopLevelDecl(decl); - FilePrinter->HandleTopLevelDecl(decl); + { + // Pretty-print the deserialized decls to a temp file. + std::ofstream DeclPP(FNameDeclPrint.c_str()); + assert (DeclPP && "Could not open file for printing out decls."); + llvm::scoped_ptr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); - if (FunctionDecl* FD = dyn_cast<FunctionDecl>(decl)) - if (FD->getBody()) { - // Construct and print a CFG. - Janitor<CFG> cfg(CFG::buildCFG(FD->getBody())); - cfg->print(DeclPP); - } + for (TranslationUnit::iterator I=NewTU->begin(), E=NewTU->end(); I!=E; ++I) + FilePrinter->HandleTopLevelDecl(*I); } + + return true; } namespace { @@ -377,14 +151,16 @@ SerializationTest::~SerializationTest() { } // Serialize and then deserialize the ASTs. - Serialize(ASTFilename, FNameDeclBefore); - Deserialize(ASTFilename, FNameDeclAfter); + bool status = Serialize(ASTFilename, FNameDeclBefore); + assert (status && "Serialization failed."); + status = Deserialize(ASTFilename, FNameDeclAfter); + assert (status && "Deserialization failed."); // Read both pretty-printed files and compare them. using llvm::MemoryBuffer; - Janitor<MemoryBuffer> + llvm::scoped_ptr<MemoryBuffer> MBufferSer(MemoryBuffer::getFile(FNameDeclBefore.c_str(), strlen(FNameDeclBefore.c_str()))); @@ -393,7 +169,7 @@ SerializationTest::~SerializationTest() { return; } - Janitor<MemoryBuffer> + llvm::scoped_ptr<MemoryBuffer> MBufferDSer(MemoryBuffer::getFile(FNameDeclAfter.c_str(), strlen(FNameDeclAfter.c_str()))); |