diff options
author | Ted Kremenek <kremenek@apple.com> | 2007-10-23 22:18:37 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2007-10-23 22:18:37 +0000 |
commit | c637e6b7afeebc6b4f751e4373715b6a8ea77272 (patch) | |
tree | af7d80893b0a99bd38fad34dc0a5019436b557f5 /Driver/SerializationTest.cpp | |
parent | b9b00ad6260b17c18195ff4a54c8b3abbf33fcc9 (diff) |
Implemented serialization for IdentifierInfo and IdentifierTable.
Updated serialization test code in the driver to test serialization of
these types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43266 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/SerializationTest.cpp')
-rw-r--r-- | Driver/SerializationTest.cpp | 288 |
1 files changed, 105 insertions, 183 deletions
diff --git a/Driver/SerializationTest.cpp b/Driver/SerializationTest.cpp index 1901591420..811dddbb74 100644 --- a/Driver/SerializationTest.cpp +++ b/Driver/SerializationTest.cpp @@ -19,226 +19,148 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "llvm/System/Path.h" -#include "llvm/Bitcode/BitstreamWriter.h" -#include <fstream> -#include <iostream> +#include "llvm/Support/Streams.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Bitcode/Serialization.h" +#include <stdio.h> + +//===----------------------------------------------------------------------===// +// Driver code. +//===----------------------------------------------------------------------===// using namespace clang; -using llvm::BitstreamWriter; -using std::cerr; -using std::cout; -using std::endl; -using std::flush; -namespace llvm { -template<typename T> struct IntrospectionTrait { - struct Flags { - enum { isPod = false, UniqueInstances = false, UniqueRefs = false }; - }; - - template<typename Introspector> - struct Ops { - static inline void Introspect(T& X, Introspector& I) { - assert (false && "Introspect not implemented."); - } +namespace { + template<typename T> + struct Janitor { + T* Obj; + Janitor(T* obj) : Obj(obj) {} + ~Janitor() { delete Obj; } }; -}; -} +} // end anonymous namespace namespace { -class SerializationTest : public ASTConsumer { - IdentifierTable* IdTable; - unsigned MainFileID; -public: - void Initialize(ASTContext& Context, unsigned mainFileID) { - IdTable = &Context.Idents; - MainFileID = mainFileID; - RunSerializationTest(); - } - - void RunSerializationTest(); - bool WriteAll(llvm::sys::Path& Filename); - - virtual void HandleTopLevelDecl(Decl *D) {} -}; - -class Writer { - std::vector<unsigned char> Buffer; - BitstreamWriter Stream; - std::ostream& Out; -public: - - enum { IdentifierTableBID = 0x8 }; - - Writer(std::ostream& out) : Stream(Buffer), Out(out) { - Buffer.reserve(256*1024); + class SerializationTest : public ASTConsumer { + IdentifierTable* IdTable; + unsigned MainFileID; + public: + void Initialize(ASTContext& Context, unsigned mainFileID) { + IdTable = &Context.Idents; + MainFileID = mainFileID; + } - // Emit the file header. - 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); - } - - ~Writer() { - Out.write((char*)&Buffer.front(), Buffer.size()); - Out.flush(); - } - - template <typename T> inline void operator()(T& x) { - llvm::IntrospectionTrait<T>::template Ops<Writer>::Introspect(x,*this); - } + ~SerializationTest() { + RunSerializationTest(); + } - template <typename T> inline void operator()(T& x, unsigned bits) { - llvm::IntrospectionTrait<T>::template Ops<Writer>::Introspect(x,bits,*this); - } - - template <typename T> inline void operator()(const T& x) { - operator()(const_cast<T&>(x)); - } - - template <typename T> inline void operator()(const T& x, unsigned bits) { - operator()(const_cast<T&>(x),bits); - } - - inline void operator()(bool X) { Stream.Emit(X,1); } - inline void operator()(unsigned X) { Stream.Emit(X,32); } - inline void operator()(unsigned X, unsigned bits, bool VBR=false) { - if (VBR) Stream.Emit(X,bits); - else Stream.Emit(X,bits); - } - - inline BitstreamWriter& getStream() { - return Stream; - } - - template <typename T> inline void EnterSubblock(unsigned CodeLen) { - Stream.EnterSubblock(8,CodeLen); - } - - inline void ExitBlock() { Stream.ExitBlock(); } - -}; - -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// External Interface. -//===----------------------------------------------------------------------===// + void RunSerializationTest(); + bool WriteTable(llvm::sys::Path& Filename, IdentifierTable* T); + IdentifierTable* ReadTable(llvm::sys::Path& Filename); + + virtual void HandleTopLevelDecl(Decl *D) {} + }; +} // end anonymous namespace ASTConsumer* clang::CreateSerializationTest() { return new SerializationTest(); } - -//===----------------------------------------------------------------------===// -// Serialization "Driver" code. -//===----------------------------------------------------------------------===// void SerializationTest::RunSerializationTest() { std::string ErrMsg; llvm::sys::Path Filename = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg); - + if (Filename.isEmpty()) { - cerr << "Error: " << ErrMsg << "\n"; + llvm::cerr << "Error: " << ErrMsg << "\n"; return; } - Filename.appendComponent("test.cfe_bc"); + Filename.appendComponent("test.ast"); if (Filename.makeUnique(true,&ErrMsg)) { - cerr << "Error: " << ErrMsg << "\n"; + llvm::cerr << "Error: " << ErrMsg << "\n"; return; } - if (!WriteAll(Filename)) - return; - - cout << "Wrote file: " << Filename.c_str() << "\n"; + llvm::cerr << "Writing out Identifier table\n"; + WriteTable(Filename,IdTable); + llvm::cerr << "Reading in Identifier Table\n"; + IdentifierTable* T = ReadTable(Filename); + Janitor<IdentifierTable> roger(T); + + Filename.appendSuffix("2"); + llvm::cerr << "Writing out Identifier table (2)\n"; + WriteTable(Filename,T); + llvm::cerr << "Reading in Identifier Table (2)\n"; + Janitor<IdentifierTable> wilco(ReadTable(Filename)); } -bool SerializationTest::WriteAll(llvm::sys::Path& Filename) { - std::ofstream Out(Filename.c_str()); +bool SerializationTest::WriteTable(llvm::sys::Path& Filename, + IdentifierTable* T) { + if (!T) + return false; - if (!Out) { - cerr << "Error: Cannot open " << Filename.c_str() << "\n"; + std::vector<unsigned char> Buffer; + Buffer.reserve(256*1024); + + llvm::BitstreamWriter Stream(Buffer); + + 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); + + llvm::Serializer S(Stream); + S.Emit(*T); + S.Flush(); + + 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 false; } - - Writer W(Out); - W(*IdTable); - - W.getStream().FlushToWord(); + + llvm::cerr << "Wrote file: " << Filename.c_str() << "\n"; return true; } -//===----------------------------------------------------------------------===// -// Serialization Methods. -//===----------------------------------------------------------------------===// - -namespace llvm { -struct IntrospectionPrimitivesFlags { - enum { isPod = true, UniqueInstances = false, UniqueRefs = false }; -}; +IdentifierTable* SerializationTest::ReadTable(llvm::sys::Path& Filename) { + llvm::MemoryBuffer* Buffer = + llvm::MemoryBuffer::getFile(Filename.c_str(), strlen(Filename.c_str())); - -template<> struct -IntrospectionTrait<bool>::Flags : public IntrospectionPrimitivesFlags {}; + if(!Buffer) { + llvm::cerr << "Error reading file\n"; + return NULL; + } -template<> struct -IntrospectionTrait<unsigned>::Flags : public IntrospectionPrimitivesFlags {}; - -template<> struct -IntrospectionTrait<short>::Flags : public IntrospectionPrimitivesFlags {}; - - - -template<> -struct IntrospectionTrait<clang::IdentifierInfo> { - - struct Flags { - enum { isPod = false, // Cannot copy via memcpy. Must use copy-ctor. - hasUniqueInstances = true, // Two pointers with different - // addreses point to objects - // that are not equal to each other. - hasUniqueReferences = true // Two (non-temporary) pointers - // will point to distinct instances. - }; - }; - - template<typename Introspector> - struct Ops { - static void Introspect(clang::IdentifierInfo& X, Introspector& I) { - // I(X.getTokenID()); - I(X.getBuiltinID(),9); // FIXME: do 9 bit specialization. - // I(X.getObjCKeywordID()); - I(X.hasMacroDefinition()); - I(X.isExtensionToken()); - I(X.isPoisoned()); - I(X.isOtherTargetMacro()); - I(X.isCPlusPlusOperatorKeyword()); - I(X.isNonPortableBuiltin()); - } - }; -}; - -template<> template<> -struct IntrospectionTrait<clang::IdentifierTable>::Ops<Writer> { - static void Introspect(clang::IdentifierTable& X, Writer& W) { - W.EnterSubblock<clang::IdentifierTable>(1); -/* - for (clang::IdentifierTable::iterator I = X.begin(), E = X.end(); - I != E; ++I) - W(I->getValue()); - */ - W.ExitBlock(); + Janitor<llvm::MemoryBuffer> AutoReleaseBuffer(Buffer); + + if (Buffer->getBufferSize() & 0x3) { + llvm::cerr << "AST file should be a multiple of 4 bytes in length\n"; + return NULL; } -}; - - + unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); + llvm::BitstreamReader Stream(BufPtr,BufPtr+Buffer->getBufferSize()); + + // Sniff for the signature. + if (Stream.Read(8) != 'B' || + Stream.Read(8) != 'C' || + Stream.Read(4) != 0xC || + Stream.Read(4) != 0xF || + Stream.Read(4) != 0xE || + Stream.Read(4) != 0x0) { + llvm::cerr << "Invalid AST-bitcode signature\n"; + return NULL; + } -} // end namespace llvm + llvm::Deserializer D(Stream); + llvm::cerr << "Materializing identifier table.\n"; + return D.Materialize<IdentifierTable>(); +} |