//=- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// // // The LLVM Compiler Infrastructure // // This file was developed by Ted Kremenek and is distributed under the // University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the interface for generic object serialization to // LLVM bitcode. // //===----------------------------------------------------------------------===// #ifndef LLVM_BITCODE_SERIALIZE #define LLVM_BITCODE_SERIALIZE #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/ADT/SmallVector.h" #include namespace llvm { template struct SerializeTrait; class Serializer { BitstreamWriter& Stream; SmallVector Record; bool inBlock; public: Serializer(BitstreamWriter& stream, unsigned BlockID = 0); ~Serializer(); template inline void Emit(const T& X) { SerializeTrait::Serialize(*this,X); } void EmitInt(unsigned X, unsigned bits); // FIXME: Substitute a better implementation which calculates the minimum // number of bits needed to serialize the enum. void EmitEnum(unsigned X, unsigned MinVal, unsigned MaxVal) { EmitInt(X,32); } void EmitCString(const char* cstr); void Flush() { if (inRecord()) EmitRecord(); } private: void EmitRecord(); inline bool inRecord() { return Record.size() > 0; } }; class Deserializer { BitstreamReader& Stream; SmallVector Record; unsigned RecIdx; public: Deserializer(BitstreamReader& stream); ~Deserializer(); template inline T& Read(T& X) { SerializeTrait::Deserialize(*this,X); return X; } template inline T* Materialize() { T* X = SerializeTrait::Instantiate(); Read(*X); return X; } uint64_t ReadInt(unsigned bits = 32); bool ReadBool() { return ReadInt(1); } // FIXME: Substitute a better implementation which calculates the minimum // number of bits needed to serialize the enum. template EnumT ReadEnum(unsigned MinVal, unsigned MaxVal) { return static_cast(ReadInt(32)); } char* ReadCString(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); void ReadCString(std::vector& buff, bool isNullTerm=false); private: void ReadRecord(); inline bool inRecord() { if (Record.size() > 0) { if (RecIdx >= Record.size()) { RecIdx = 0; Record.clear(); return false; } else return true; } else return false; } }; template struct SerializeIntTrait { static inline void Serialize(Serializer& S, uintty X) { S.EmitInt(X,Bits); } static inline void Deserialize(Deserializer& S, uintty& X) { X = (uintty) S.ReadInt(Bits); } }; template <> struct SerializeTrait : public SerializeIntTrait {}; template <> struct SerializeTrait : public SerializeIntTrait {}; template <> struct SerializeTrait : public SerializeIntTrait {}; template <> struct SerializeTrait : public SerializeIntTrait {}; } // end namespace llvm #endif