LLVM API Documentation
00001 //==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the interface for generic object serialization to 00011 // LLVM bitcode. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_BITCODE_SERIALIZE_OUTPUT 00016 #define LLVM_BITCODE_SERIALIZE_OUTPUT 00017 00018 #include "llvm/Bitcode/Serialization.h" 00019 #include "llvm/Bitcode/BitstreamWriter.h" 00020 #include "llvm/ADT/SmallVector.h" 00021 #include "llvm/ADT/DenseMap.h" 00022 00023 namespace llvm { 00024 00025 class Serializer { 00026 BitstreamWriter& Stream; 00027 SmallVector<uint64_t,10> Record; 00028 unsigned BlockLevel; 00029 00030 typedef DenseMap<const void*,unsigned> MapTy; 00031 MapTy PtrMap; 00032 00033 public: 00034 explicit Serializer(BitstreamWriter& stream); 00035 ~Serializer(); 00036 00037 //==------------------------------------------------==// 00038 // Template-based dispatch to emit arbitrary types. 00039 //==------------------------------------------------==// 00040 00041 template <typename T> 00042 inline void Emit(const T& X) { SerializeTrait<T>::Emit(*this,X); } 00043 00044 //==------------------------------------------------==// 00045 // Methods to emit primitive types. 00046 //==------------------------------------------------==// 00047 00048 void EmitInt(uint64_t X); 00049 void EmitSInt(int64_t X); 00050 00051 inline void EmitBool(bool X) { EmitInt(X); } 00052 void EmitCStr(const char* beg, const char* end); 00053 void EmitCStr(const char* cstr); 00054 00055 void EmitPtr(const void* ptr) { EmitInt(getPtrId(ptr)); } 00056 00057 template <typename T> 00058 inline void EmitRef(const T& ref) { EmitPtr(&ref); } 00059 00060 // Emit a pointer and the object pointed to. (This has no relation to the 00061 // OwningPtr<> class.) 00062 template <typename T> 00063 inline void EmitOwnedPtr(T* ptr) { 00064 EmitPtr(ptr); 00065 if (ptr) SerializeTrait<T>::Emit(*this,*ptr); 00066 } 00067 00068 00069 //==------------------------------------------------==// 00070 // Batch emission of pointers. 00071 //==------------------------------------------------==// 00072 00073 template <typename T1, typename T2> 00074 void BatchEmitOwnedPtrs(T1* p1, T2* p2) { 00075 EmitPtr(p1); 00076 EmitPtr(p2); 00077 if (p1) SerializeTrait<T1>::Emit(*this,*p1); 00078 if (p2) SerializeTrait<T2>::Emit(*this,*p2); 00079 } 00080 00081 template <typename T1, typename T2, typename T3> 00082 void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) { 00083 EmitPtr(p1); 00084 EmitPtr(p2); 00085 EmitPtr(p3); 00086 if (p1) SerializeTrait<T1>::Emit(*this,*p1); 00087 if (p2) SerializeTrait<T2>::Emit(*this,*p2); 00088 if (p3) SerializeTrait<T3>::Emit(*this,*p3); 00089 } 00090 00091 template <typename T1, typename T2, typename T3, typename T4> 00092 void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3, T4& p4) { 00093 EmitPtr(p1); 00094 EmitPtr(p2); 00095 EmitPtr(p3); 00096 EmitPtr(p4); 00097 if (p1) SerializeTrait<T1>::Emit(*this,*p1); 00098 if (p2) SerializeTrait<T2>::Emit(*this,*p2); 00099 if (p3) SerializeTrait<T3>::Emit(*this,*p3); 00100 if (p4) SerializeTrait<T4>::Emit(*this,*p4); 00101 } 00102 00103 template <typename T> 00104 void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) { 00105 for (unsigned i = 0; i < NumPtrs; ++i) 00106 EmitPtr(Ptrs[i]); 00107 00108 for (unsigned i = 0; i < NumPtrs; ++i) 00109 if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]); 00110 } 00111 00112 template <typename T1, typename T2> 00113 void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) { 00114 00115 for (unsigned i = 0; i < NumT1Ptrs; ++i) 00116 EmitPtr(Ptrs[i]); 00117 00118 EmitPtr(p2); 00119 00120 for (unsigned i = 0; i < NumT1Ptrs; ++i) 00121 if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]); 00122 00123 if (p2) SerializeTrait<T2>::Emit(*this,*p2); 00124 } 00125 00126 template <typename T1, typename T2, typename T3> 00127 void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, 00128 T2* p2, T3* p3) { 00129 00130 for (unsigned i = 0; i < NumT1Ptrs; ++i) 00131 EmitPtr(Ptrs[i]); 00132 00133 EmitPtr(p2); 00134 EmitPtr(p3); 00135 00136 for (unsigned i = 0; i < NumT1Ptrs; ++i) 00137 if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]); 00138 00139 if (p2) SerializeTrait<T2>::Emit(*this,*p2); 00140 if (p3) SerializeTrait<T3>::Emit(*this,*p3); 00141 } 00142 00143 //==------------------------------------------------==// 00144 // Emitter Functors 00145 //==------------------------------------------------==// 00146 00147 template <typename T> 00148 struct Emitter0 { 00149 Serializer& S; 00150 Emitter0(Serializer& s) : S(s) {} 00151 void operator()(const T& x) const { 00152 SerializeTrait<T>::Emit(S,x); 00153 } 00154 }; 00155 00156 template <typename T, typename Arg1> 00157 struct Emitter1 { 00158 Serializer& S; 00159 Arg1 A1; 00160 00161 Emitter1(Serializer& s, Arg1 a1) : S(s), A1(a1) {} 00162 void operator()(const T& x) const { 00163 SerializeTrait<T>::Emit(S,x,A1); 00164 } 00165 }; 00166 00167 template <typename T, typename Arg1, typename Arg2> 00168 struct Emitter2 { 00169 Serializer& S; 00170 Arg1 A1; 00171 Arg2 A2; 00172 00173 Emitter2(Serializer& s, Arg1 a1, Arg2 a2) : S(s), A1(a1), A2(a2) {} 00174 void operator()(const T& x) const { 00175 SerializeTrait<T>::Emit(S,x,A1,A2); 00176 } 00177 }; 00178 00179 template <typename T> 00180 Emitter0<T> MakeEmitter() { 00181 return Emitter0<T>(*this); 00182 } 00183 00184 template <typename T, typename Arg1> 00185 Emitter1<T,Arg1> MakeEmitter(Arg1 a1) { 00186 return Emitter1<T,Arg1>(*this,a1); 00187 } 00188 00189 template <typename T, typename Arg1, typename Arg2> 00190 Emitter2<T,Arg1,Arg2> MakeEmitter(Arg1 a1, Arg2 a2) { 00191 return Emitter2<T,Arg1,Arg2>(*this,a1,a2); 00192 } 00193 00194 //==------------------------------------------------==// 00195 // Misc. query and block/record manipulation methods. 00196 //==------------------------------------------------==// 00197 00198 bool isRegistered(const void* p) const; 00199 00200 void FlushRecord() { if (inRecord()) EmitRecord(); } 00201 void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3); 00202 void ExitBlock(); 00203 00204 private: 00205 void EmitRecord(); 00206 inline bool inRecord() { return Record.size() > 0; } 00207 SerializedPtrID getPtrId(const void* ptr); 00208 }; 00209 00210 } // end namespace llvm 00211 #endif