diff options
Diffstat (limited to 'include/llvm/Bitcode/Serialize.h')
-rw-r--r-- | include/llvm/Bitcode/Serialize.h | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/include/llvm/Bitcode/Serialize.h b/include/llvm/Bitcode/Serialize.h new file mode 100644 index 000000000000..6fe4f0228d54 --- /dev/null +++ b/include/llvm/Bitcode/Serialize.h @@ -0,0 +1,211 @@ +//==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file 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" +#include "llvm/ADT/DenseMap.h" + +namespace llvm { + +class Serializer { + BitstreamWriter& Stream; + SmallVector<uint64_t,10> Record; + unsigned BlockLevel; + + typedef DenseMap<const void*,unsigned> MapTy; + MapTy PtrMap; + +public: + explicit Serializer(BitstreamWriter& stream); + ~Serializer(); + + //==------------------------------------------------==// + // Template-based dispatch to emit arbitrary types. + //==------------------------------------------------==// + + template <typename T> + inline void Emit(const T& X) { SerializeTrait<T>::Emit(*this,X); } + + //==------------------------------------------------==// + // Methods to emit primitive types. + //==------------------------------------------------==// + + void EmitInt(uint64_t X); + void EmitSInt(int64_t X); + + inline void EmitBool(bool X) { EmitInt(X); } + void EmitCStr(const char* beg, const char* end); + void EmitCStr(const char* cstr); + + void EmitPtr(const void* ptr) { EmitInt(getPtrId(ptr)); } + + template <typename T> + inline void EmitRef(const T& ref) { EmitPtr(&ref); } + + // Emit a pointer and the object pointed to. (This has no relation to the + // OwningPtr<> class.) + template <typename T> + inline void EmitOwnedPtr(T* ptr) { + EmitPtr(ptr); + if (ptr) SerializeTrait<T>::Emit(*this,*ptr); + } + + + //==------------------------------------------------==// + // Batch emission of pointers. + //==------------------------------------------------==// + + template <typename T1, typename T2> + void BatchEmitOwnedPtrs(T1* p1, T2* p2) { + EmitPtr(p1); + EmitPtr(p2); + if (p1) SerializeTrait<T1>::Emit(*this,*p1); + if (p2) SerializeTrait<T2>::Emit(*this,*p2); + } + + template <typename T1, typename T2, typename T3> + void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) { + EmitPtr(p1); + EmitPtr(p2); + EmitPtr(p3); + if (p1) SerializeTrait<T1>::Emit(*this,*p1); + if (p2) SerializeTrait<T2>::Emit(*this,*p2); + if (p3) SerializeTrait<T3>::Emit(*this,*p3); + } + + template <typename T1, typename T2, typename T3, typename T4> + void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3, T4& p4) { + EmitPtr(p1); + EmitPtr(p2); + EmitPtr(p3); + EmitPtr(p4); + if (p1) SerializeTrait<T1>::Emit(*this,*p1); + if (p2) SerializeTrait<T2>::Emit(*this,*p2); + if (p3) SerializeTrait<T3>::Emit(*this,*p3); + if (p4) SerializeTrait<T4>::Emit(*this,*p4); + } + + template <typename T> + void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) { + for (unsigned i = 0; i < NumPtrs; ++i) + EmitPtr(Ptrs[i]); + + for (unsigned i = 0; i < NumPtrs; ++i) + if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]); + } + + template <typename T1, typename T2> + void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) { + + for (unsigned i = 0; i < NumT1Ptrs; ++i) + EmitPtr(Ptrs[i]); + + EmitPtr(p2); + + for (unsigned i = 0; i < NumT1Ptrs; ++i) + if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]); + + if (p2) SerializeTrait<T2>::Emit(*this,*p2); + } + + template <typename T1, typename T2, typename T3> + void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, + T2* p2, T3* p3) { + + for (unsigned i = 0; i < NumT1Ptrs; ++i) + EmitPtr(Ptrs[i]); + + EmitPtr(p2); + EmitPtr(p3); + + for (unsigned i = 0; i < NumT1Ptrs; ++i) + if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]); + + if (p2) SerializeTrait<T2>::Emit(*this,*p2); + if (p3) SerializeTrait<T3>::Emit(*this,*p3); + } + + //==------------------------------------------------==// + // Emitter Functors + //==------------------------------------------------==// + + template <typename T> + struct Emitter0 { + Serializer& S; + Emitter0(Serializer& s) : S(s) {} + void operator()(const T& x) const { + SerializeTrait<T>::Emit(S,x); + } + }; + + template <typename T, typename Arg1> + struct Emitter1 { + Serializer& S; + Arg1 A1; + + Emitter1(Serializer& s, Arg1 a1) : S(s), A1(a1) {} + void operator()(const T& x) const { + SerializeTrait<T>::Emit(S,x,A1); + } + }; + + template <typename T, typename Arg1, typename Arg2> + struct Emitter2 { + Serializer& S; + Arg1 A1; + Arg2 A2; + + Emitter2(Serializer& s, Arg1 a1, Arg2 a2) : S(s), A1(a1), A2(a2) {} + void operator()(const T& x) const { + SerializeTrait<T>::Emit(S,x,A1,A2); + } + }; + + template <typename T> + Emitter0<T> MakeEmitter() { + return Emitter0<T>(*this); + } + + template <typename T, typename Arg1> + Emitter1<T,Arg1> MakeEmitter(Arg1 a1) { + return Emitter1<T,Arg1>(*this,a1); + } + + template <typename T, typename Arg1, typename Arg2> + Emitter2<T,Arg1,Arg2> MakeEmitter(Arg1 a1, Arg2 a2) { + return Emitter2<T,Arg1,Arg2>(*this,a1,a2); + } + + //==------------------------------------------------==// + // Misc. query and block/record manipulation methods. + //==------------------------------------------------==// + + bool isRegistered(const void* p) const; + + void FlushRecord() { if (inRecord()) EmitRecord(); } + void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3); + void ExitBlock(); + +private: + void EmitRecord(); + inline bool inRecord() { return Record.size() > 0; } + SerializedPtrID getPtrId(const void* ptr); +}; + +} // end namespace llvm +#endif |