diff --git a/include/llvm/Bitcode/Deserialize.h b/include/llvm/Bitcode/Deserialize.h new file mode 100644 index 00000000000..6ee09aaa344 --- /dev/null +++ b/include/llvm/Bitcode/Deserialize.h @@ -0,0 +1,74 @@ +//=- Deserialize.h - Generic Object Deserialization from 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 deserialization from +// LLVM bitcode. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_SERIALIZE_INPUT +#define LLVM_BITCODE_SERIALIZE_INPUT + +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitcode/Serialization.h" +#include + +namespace llvm { + +class Deserializer { + BitstreamReader& Stream; + SmallVector Record; + unsigned RecIdx; +public: + Deserializer(BitstreamReader& stream); + ~Deserializer(); + + template + inline T& Read(T& X) { + SerializeTrait::Read(*this,X); + return X; + } + + template + inline T* Materialize() { + return SerializeTrait::Materialize(*this); + } + + uint64_t ReadInt(); + bool ReadBool() { return ReadInt() ? true : false; } + + // 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* ReadCStr(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); + void ReadCStr(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; + } +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/Bitcode/Serialization.h b/include/llvm/Bitcode/Serialization.h index eeaac4a8a39..935452cc1b8 100644 --- a/include/llvm/Bitcode/Serialization.h +++ b/include/llvm/Bitcode/Serialization.h @@ -1,4 +1,4 @@ - //=- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// +//==- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -15,114 +15,26 @@ #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 { +class Serializer; +class Deserializer; 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); +#define SERIALIZE_INT_TRAIT(TYPE)\ +template <> struct SerializeTrait {\ + static void Emit(Serializer& S, TYPE X);\ + static void Read(Deserializer& S, TYPE& X); }; - 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(); +SERIALIZE_INT_TRAIT(bool) +SERIALIZE_INT_TRAIT(unsigned char) +SERIALIZE_INT_TRAIT(unsigned short) +SERIALIZE_INT_TRAIT(unsigned int) +SERIALIZE_INT_TRAIT(unsigned long) +SERIALIZE_INT_TRAIT(unsigned long long) - 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) ? true : false; } - - // 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 {}; - - +#undef SERIALIZE_INT_TRAIT } // end namespace llvm + #endif diff --git a/include/llvm/Bitcode/Serialize.h b/include/llvm/Bitcode/Serialize.h new file mode 100644 index 00000000000..061ccaf7c30 --- /dev/null +++ b/include/llvm/Bitcode/Serialize.h @@ -0,0 +1,48 @@ +//==- Serialize.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_OUTPUT +#define LLVM_BITCODE_SERIALIZE_OUTPUT + +#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +class Serializer { + BitstreamWriter& Stream; + SmallVector Record; + bool inBlock; +public: + Serializer(BitstreamWriter& stream, unsigned BlockID = 0); + ~Serializer(); + + template + inline void Emit(const T& X) { SerializeTrait::Emit(*this,X); } + + void EmitInt(unsigned X); + void EmitBool(bool X) { EmitInt(X); } + void EmitCStr(const char* beg, const char* end); + void EmitCStr(const char* cstr); + + void Flush() { if (inRecord()) EmitRecord(); } + +private: + void EmitRecord(); + inline bool inRecord() { return Record.size() > 0; } +}; + +} // end namespace llvm +#endif diff --git a/lib/Bitcode/Reader/Deserialize.cpp b/lib/Bitcode/Reader/Deserialize.cpp index ccd929a440d..cf5fe205eba 100644 --- a/lib/Bitcode/Reader/Deserialize.cpp +++ b/lib/Bitcode/Reader/Deserialize.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/Deserialize.h" using namespace llvm; @@ -27,31 +27,29 @@ Deserializer::~Deserializer() { void Deserializer::ReadRecord() { // FIXME: Check if we haven't run off the edge of the stream. // FIXME: Handle abbreviations. - unsigned Code = Stream.ReadCode(); + // FIXME: Check for the correct code. - assert (Record.size() == 0); - - Stream.ReadRecord(Code,Record); - + unsigned Code = Stream.ReadCode(); + + assert (Record.size() == 0); + Stream.ReadRecord(Code,Record); assert (Record.size() > 0); } -uint64_t Deserializer::ReadInt(unsigned Bits) { +uint64_t Deserializer::ReadInt() { // FIXME: Any error recovery/handling with incomplete or bad files? if (!inRecord()) ReadRecord(); - // FIXME: check for loss of precision in read (compare to Bits) return Record[RecIdx++]; } -char* Deserializer::ReadCString(char* cstr, unsigned MaxLen, bool isNullTerm) { +char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) { if (cstr == NULL) MaxLen = 0; // Zero this just in case someone does something funny. - unsigned len = ReadInt(32); + unsigned len = ReadInt(); - // FIXME: perform dynamic checking of lengths? assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen); if (!cstr) @@ -60,7 +58,7 @@ char* Deserializer::ReadCString(char* cstr, unsigned MaxLen, bool isNullTerm) { assert (cstr != NULL); for (unsigned i = 0; i < len; ++i) - cstr[i] = ReadInt(8); + cstr[i] = (char) ReadInt(); if (isNullTerm) cstr[len+1] = '\0'; @@ -68,16 +66,27 @@ char* Deserializer::ReadCString(char* cstr, unsigned MaxLen, bool isNullTerm) { return cstr; } -void Deserializer::ReadCString(std::vector& buff, bool isNullTerm) { - buff.clear(); +void Deserializer::ReadCStr(std::vector& buff, bool isNullTerm) { + unsigned len = ReadInt(); - unsigned len = ReadInt(32); - + buff.clear(); buff.reserve(len); for (unsigned i = 0; i < len; ++i) - buff.push_back(ReadInt(8)); + buff.push_back((char) ReadInt()); if (isNullTerm) buff.push_back('\0'); } + + +#define INT_READ(TYPE)\ +void SerializeTrait::Read(Deserializer& D, TYPE& X) {\ + X = (TYPE) D.ReadInt(); } + +INT_READ(bool) +INT_READ(unsigned char) +INT_READ(unsigned short) +INT_READ(unsigned int) +INT_READ(unsigned long) +INT_READ(unsigned long long) diff --git a/lib/Bitcode/Writer/Serialize.cpp b/lib/Bitcode/Writer/Serialize.cpp index 9fbb97de69f..72939334bc2 100644 --- a/lib/Bitcode/Writer/Serialize.cpp +++ b/lib/Bitcode/Writer/Serialize.cpp @@ -11,7 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/Serialize.h" +#include "string.h" using namespace llvm; @@ -37,16 +38,31 @@ void Serializer::EmitRecord() { Record.clear(); } -void Serializer::EmitInt(unsigned X, unsigned bits) { +void Serializer::EmitInt(unsigned X) { Record.push_back(X); } -void Serializer::EmitCString(const char* cstr) { - unsigned l = strlen(cstr); - Record.push_back(l); +void Serializer::EmitCStr(const char* s, const char* end) { + Record.push_back(end - s); - for (unsigned i = 0; i < l; i++) - Record.push_back(cstr[i]); + while(s != end) { + Record.push_back(*s); + ++s; + } EmitRecord(); } + +void Serializer::EmitCStr(const char* s) { + EmitCStr(s,s+strlen(s)); +} + +#define INT_EMIT(TYPE)\ +void SerializeTrait::Emit(Serializer&S, TYPE X) { S.EmitInt(X); } + +INT_EMIT(bool) +INT_EMIT(unsigned char) +INT_EMIT(unsigned short) +INT_EMIT(unsigned int) +INT_EMIT(unsigned long) +INT_EMIT(unsigned long long)