LLVM API Documentation

Deserialize.h

Go to the documentation of this file.
00001 //=- Deserialize.h - Generic Object Deserialization from 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 deserialization from
00011 // LLVM bitcode.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_BITCODE_SERIALIZE_INPUT
00016 #define LLVM_BITCODE_SERIALIZE_INPUT
00017 
00018 #include "llvm/Bitcode/BitstreamReader.h"
00019 #include "llvm/Bitcode/Serialization.h"
00020 #include "llvm/ADT/DenseMap.h"
00021 #include "llvm/ADT/SmallVector.h"
00022 #include "llvm/Support/Allocator.h"
00023 #include "llvm/Support/DataTypes.h"
00024 #include <vector>
00025 
00026 namespace llvm {
00027   
00028 class Deserializer {  
00029 
00030   //===----------------------------------------------------------===//
00031   // Internal type definitions.
00032   //===----------------------------------------------------------===//
00033   
00034   struct BPNode {
00035     BPNode* Next;
00036     uintptr_t& PtrRef;
00037     
00038     BPNode(BPNode* n, uintptr_t& pref) 
00039       : Next(n), PtrRef(pref) {
00040         PtrRef = 0;
00041       }
00042   };
00043   
00044   struct BPEntry { 
00045     union { BPNode* Head; void* Ptr; };
00046     
00047     BPEntry() : Head(NULL) {}
00048     
00049     static inline bool isPod() { return true; }
00050     
00051     void SetPtr(BPNode*& FreeList, void* P);    
00052   };  
00053   
00054   class BPKey {
00055     unsigned Raw;
00056     
00057   public:
00058     BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
00059     BPKey(unsigned code, unsigned) : Raw(code) {}
00060     
00061     void MarkFinal() { Raw |= 0x1; }
00062     bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
00063     SerializedPtrID getID() const { return Raw >> 1; }
00064     
00065     static inline BPKey getEmptyKey() { return BPKey(0,0); }
00066     static inline BPKey getTombstoneKey() { return BPKey(1,0); }
00067     static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
00068 
00069     static bool isEqual(const BPKey& K1, const BPKey& K2) {
00070       return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
00071     }
00072     
00073     static bool isPod() { return true; }
00074   };
00075   
00076   typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy;
00077 
00078   //===----------------------------------------------------------===//
00079   // Publicly visible types.
00080   //===----------------------------------------------------------===//
00081   
00082 public:  
00083   struct Location {
00084     uint64_t BitNo;
00085     unsigned BlockID;
00086     unsigned NumWords;
00087     
00088     Location(uint64_t bit, unsigned bid, unsigned words) 
00089     : BitNo(bit), BlockID(bid), NumWords(words) {}
00090     
00091     Location() : BitNo(0), BlockID(0), NumWords(0) {}
00092 
00093     Location& operator=(Location& RHS) {
00094       BitNo = RHS.BitNo;
00095       BlockID = RHS.BlockID;
00096       NumWords = RHS.NumWords;
00097       return *this;
00098     }
00099     
00100     bool operator==(const Location& RHS) const { return BitNo == RHS.BitNo; }    
00101     bool operator!=(const Location& RHS) const { return BitNo != RHS.BitNo; }
00102     
00103     bool contains(const Location& RHS) const {
00104       if (RHS.BitNo < BitNo)
00105         return false;
00106 
00107       if ((RHS.BitNo - BitNo) >> 5 < NumWords)
00108         return true;
00109       
00110       return false;
00111     }
00112   };
00113   
00114   //===----------------------------------------------------------===//
00115   // Internal data members.
00116   //===----------------------------------------------------------===//
00117 
00118 private:
00119   BitstreamReader& Stream;
00120   SmallVector<uint64_t,20> Record;
00121   unsigned RecIdx;
00122   BumpPtrAllocator Allocator;
00123   BPNode* FreeList;
00124   MapTy BPatchMap;
00125   llvm::SmallVector<Location,8> BlockStack;
00126   unsigned AbbrevNo;
00127   unsigned RecordCode;
00128   uint64_t StreamStart;
00129   
00130   //===----------------------------------------------------------===//
00131   // Public Interface.
00132   //===----------------------------------------------------------===//
00133   
00134 public:  
00135   Deserializer(BitstreamReader& stream);
00136   ~Deserializer();
00137 
00138   uint64_t ReadInt();
00139   int64_t ReadSInt();
00140   SerializedPtrID ReadPtrID() { return (SerializedPtrID) ReadInt(); }
00141   
00142   
00143   bool ReadBool() {
00144     return ReadInt() ? true : false;
00145   }
00146 
00147   template <typename T>
00148   inline T& Read(T& X) {
00149     SerializeTrait<T>::Read(*this,X);
00150     return X;
00151   }
00152 
00153   template <typename T>
00154   inline T* Create() {
00155     return SerializeTrait<T>::Create(*this);
00156   }
00157   
00158   char* ReadCStr(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true);
00159   void ReadCStr(std::vector<char>& buff, bool isNullTerm=false, unsigned Idx=0);
00160 
00161   template <typename T>
00162   inline T* ReadOwnedPtr(bool AutoRegister = true) {
00163     SerializedPtrID PtrID = ReadPtrID();    
00164 
00165     if (!PtrID)
00166       return NULL;
00167     
00168     T* x = SerializeTrait<T>::Create(*this);
00169 
00170     if (AutoRegister)
00171       RegisterPtr(PtrID,x);
00172     
00173     return x;
00174   }
00175 
00176   template <typename T, typename Arg1>
00177   inline T* ReadOwnedPtr(Arg1& arg1, bool AutoRegister = true) {
00178     SerializedPtrID PtrID = ReadPtrID();
00179 
00180     if (!PtrID)
00181       return NULL;
00182 
00183     T* x = SerializeTrait<T>::Create(*this, arg1);
00184 
00185     if (AutoRegister)
00186       RegisterPtr(PtrID,x);
00187 
00188     return x;
00189   }
00190 
00191   template <typename T>
00192   inline void ReadOwnedPtr(T*& Ptr, bool AutoRegister = true) {
00193     Ptr = ReadOwnedPtr<T>(AutoRegister);
00194   }
00195   
00196   template <typename T1, typename T2>
00197   void BatchReadOwnedPtrs(T1*& P1, T2*& P2,
00198                           bool A1=true, bool A2=true) {
00199 
00200     SerializedPtrID ID1 = ReadPtrID();
00201     SerializedPtrID ID2 = ReadPtrID();
00202 
00203     P1 = (ID1) ? SerializeTrait<T1>::Create(*this) : NULL;
00204     if (ID1 && A1) RegisterPtr(ID1,P1);
00205 
00206     P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL;
00207     if (ID2 && A2) RegisterPtr(ID2,P2);
00208   }
00209 
00210   template <typename T1, typename T2, typename Arg1>
00211   void BatchReadOwnedPtrs(T1*& P1, T2*& P2, Arg1& arg1,
00212                           bool A1=true, bool A2=true) {
00213 
00214     SerializedPtrID ID1 = ReadPtrID();
00215     SerializedPtrID ID2 = ReadPtrID();
00216 
00217     P1 = (ID1) ? SerializeTrait<T1>::Create(*this, arg1) : NULL;
00218     if (ID1 && A1) RegisterPtr(ID1,P1);
00219 
00220     P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL;
00221     if (ID2 && A2) RegisterPtr(ID2,P2);
00222   }
00223 
00224   template <typename T1, typename T2, typename T3>
00225   void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3,
00226                           bool A1=true, bool A2=true, bool A3=true) {
00227     
00228     SerializedPtrID ID1 = ReadPtrID();
00229     SerializedPtrID ID2 = ReadPtrID();
00230     SerializedPtrID ID3 = ReadPtrID();
00231     
00232     P1 = (ID1) ? SerializeTrait<T1>::Create(*this) : NULL;
00233     if (ID1 && A1) RegisterPtr(ID1,P1);    
00234     
00235     P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL;
00236     if (ID2 && A2) RegisterPtr(ID2,P2);
00237     
00238     P3 = (ID3) ? SerializeTrait<T3>::Create(*this) : NULL;
00239     if (ID3 && A3) RegisterPtr(ID3,P3);
00240   }
00241 
00242   template <typename T1, typename T2, typename T3, typename Arg1>
00243   void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3, Arg1& arg1,
00244                           bool A1=true, bool A2=true, bool A3=true) {
00245 
00246     SerializedPtrID ID1 = ReadPtrID();
00247     SerializedPtrID ID2 = ReadPtrID();
00248     SerializedPtrID ID3 = ReadPtrID();
00249 
00250     P1 = (ID1) ? SerializeTrait<T1>::Create(*this, arg1) : NULL;
00251     if (ID1 && A1) RegisterPtr(ID1,P1);
00252 
00253     P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL;
00254     if (ID2 && A2) RegisterPtr(ID2,P2);
00255 
00256     P3 = (ID3) ? SerializeTrait<T3>::Create(*this, arg1) : NULL;
00257     if (ID3 && A3) RegisterPtr(ID3,P3);
00258   }
00259 
00260   template <typename T>
00261   void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, bool AutoRegister=true) {
00262     llvm::SmallVector<SerializedPtrID,10> BatchIDVec;
00263     
00264     for (unsigned i = 0; i < NumPtrs; ++i)
00265       BatchIDVec.push_back(ReadPtrID());
00266     
00267     for (unsigned i = 0; i < NumPtrs; ++i) {
00268       SerializedPtrID& PtrID = BatchIDVec[i];
00269       
00270       T* p = PtrID ? SerializeTrait<T>::Create(*this) : NULL;
00271       
00272       if (PtrID && AutoRegister)
00273         RegisterPtr(PtrID,p);
00274       
00275       Ptrs[i] = p;
00276     }
00277   }
00278   
00279   template <typename T, typename Arg1>
00280   void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, Arg1& arg1,
00281                           bool AutoRegister=true) {
00282 
00283     llvm::SmallVector<SerializedPtrID,10> BatchIDVec;
00284 
00285     for (unsigned i = 0; i < NumPtrs; ++i)
00286       BatchIDVec.push_back(ReadPtrID());
00287 
00288     for (unsigned i = 0; i < NumPtrs; ++i) {
00289       SerializedPtrID& PtrID = BatchIDVec[i];
00290 
00291       T* p = PtrID ? SerializeTrait<T>::Create(*this, arg1) : NULL;
00292 
00293       if (PtrID && AutoRegister)
00294         RegisterPtr(PtrID,p);
00295 
00296       Ptrs[i] = p;
00297     }
00298   }
00299 
00300   template <typename T1, typename T2>
00301   void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, T2*& P2,
00302                           bool A1=true, bool A2=true) {
00303     
00304     llvm::SmallVector<SerializedPtrID,10> BatchIDVec;
00305 
00306     for (unsigned i = 0; i < NumT1Ptrs; ++i)
00307       BatchIDVec.push_back(ReadPtrID());
00308     
00309     SerializedPtrID ID2 = ReadPtrID();
00310     
00311     for (unsigned i = 0; i < NumT1Ptrs; ++i) {
00312       SerializedPtrID& PtrID = BatchIDVec[i];
00313       
00314       T1* p = PtrID ? SerializeTrait<T1>::Create(*this) : NULL;
00315       
00316       if (PtrID && A1)
00317         RegisterPtr(PtrID,p);
00318       
00319       Ptrs[i] = p;
00320     }
00321     
00322     P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL;
00323     if (ID2 && A2) RegisterPtr(ID2,P2);    
00324   }    
00325   
00326   template <typename T1, typename T2, typename Arg1>
00327   void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, T2*& P2, Arg1& arg1,
00328                           bool A1=true, bool A2=true) {
00329 
00330     llvm::SmallVector<SerializedPtrID,10> BatchIDVec;
00331 
00332     for (unsigned i = 0; i < NumT1Ptrs; ++i)
00333       BatchIDVec.push_back(ReadPtrID());
00334 
00335     SerializedPtrID ID2 = ReadPtrID();
00336 
00337     for (unsigned i = 0; i < NumT1Ptrs; ++i) {
00338       SerializedPtrID& PtrID = BatchIDVec[i];
00339 
00340       T1* p = PtrID ? SerializeTrait<T1>::Create(*this, arg1) : NULL;
00341 
00342       if (PtrID && A1)
00343         RegisterPtr(PtrID,p);
00344 
00345       Ptrs[i] = p;
00346     }
00347 
00348     P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL;
00349     if (ID2 && A2) RegisterPtr(ID2,P2);
00350   }
00351 
00352   template <typename T1, typename T2, typename T3>
00353   void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs, 
00354                           T2*& P2, T3*& P3,
00355                           bool A1=true, bool A2=true, bool A3=true) {
00356     
00357     llvm::SmallVector<SerializedPtrID,10> BatchIDVec;
00358     
00359     for (unsigned i = 0; i < NumT1Ptrs; ++i)
00360       BatchIDVec.push_back(ReadPtrID());
00361     
00362     SerializedPtrID ID2 = ReadPtrID();
00363     SerializedPtrID ID3 = ReadPtrID();    
00364     
00365     for (unsigned i = 0; i < NumT1Ptrs; ++i) {
00366       SerializedPtrID& PtrID = BatchIDVec[i];
00367       
00368       T1* p = PtrID ? SerializeTrait<T1>::Create(*this) : NULL;
00369       
00370       if (PtrID && A1)
00371         RegisterPtr(PtrID,p);
00372       
00373       Ptrs[i] = p;
00374     }
00375     
00376     P2 = (ID2) ? SerializeTrait<T2>::Create(*this) : NULL;
00377     if (ID2 && A2) RegisterPtr(ID2,P2);
00378     
00379     P3 = (ID3) ? SerializeTrait<T3>::Create(*this) : NULL;
00380     if (ID3 && A3) RegisterPtr(ID3,P3);    
00381   }    
00382 
00383   template <typename T1, typename T2, typename T3, typename Arg1>
00384   void BatchReadOwnedPtrs(unsigned NumT1Ptrs, T1** Ptrs,
00385                           T2*& P2, T3*& P3, Arg1& arg1,
00386                           bool A1=true, bool A2=true, bool A3=true) {
00387 
00388     llvm::SmallVector<SerializedPtrID,10> BatchIDVec;
00389 
00390     for (unsigned i = 0; i < NumT1Ptrs; ++i)
00391       BatchIDVec.push_back(ReadPtrID());
00392 
00393     SerializedPtrID ID2 = ReadPtrID();
00394     SerializedPtrID ID3 = ReadPtrID();
00395 
00396     for (unsigned i = 0; i < NumT1Ptrs; ++i) {
00397       SerializedPtrID& PtrID = BatchIDVec[i];
00398 
00399       T1* p = PtrID ? SerializeTrait<T1>::Create(*this, arg1) : NULL;
00400 
00401       if (PtrID && A1)
00402         RegisterPtr(PtrID,p);
00403 
00404       Ptrs[i] = p;
00405     }
00406 
00407     P2 = (ID2) ? SerializeTrait<T2>::Create(*this, arg1) : NULL;
00408     if (ID2 && A2) RegisterPtr(ID2,P2);
00409 
00410     P3 = (ID3) ? SerializeTrait<T3>::Create(*this, arg1) : NULL;
00411     if (ID3 && A3) RegisterPtr(ID3,P3);
00412   }
00413 
00414   template <typename T>
00415   void ReadPtr(T*& PtrRef, bool AllowBackpatch = true) {
00416     ReadUIntPtr(reinterpret_cast<uintptr_t&>(PtrRef), AllowBackpatch);
00417   }
00418   
00419   template <typename T>
00420   void ReadPtr(const T*& PtrRef, bool AllowBackpatch = true) {
00421     ReadPtr(const_cast<T*&>(PtrRef), AllowBackpatch);
00422   }
00423   
00424   
00425   template <typename T>
00426   void ReadPtr(T*& PtrRef, const SerializedPtrID& PtrID, 
00427                bool AllowBackpatch = true) {
00428     ReadUIntPtr(reinterpret_cast<uintptr_t&>(PtrRef), PtrID, AllowBackpatch);
00429   }
00430   
00431   template <typename T>
00432   void ReadPtr(const T*& PtrRef, const SerializedPtrID& PtrID, 
00433                bool AllowBackpatch = true) {
00434     
00435     ReadPtr(const_cast<T*&>(PtrRef), PtrID, AllowBackpatch);
00436   }
00437   
00438   template <typename T>
00439   T* ReadPtr() { T* x = 0; ReadPtr<T>(x,false); return x; }
00440 
00441   void ReadUIntPtr(uintptr_t& PtrRef, const SerializedPtrID& PtrID, 
00442                    bool AllowBackpatch = true);
00443   
00444   void ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch = true) {
00445     ReadUIntPtr(PtrRef,ReadPtrID(),AllowBackpatch);
00446   }
00447   
00448   template <typename T>
00449   T& ReadRef() {
00450     T* p = reinterpret_cast<T*>(ReadInternalRefPtr());
00451     return *p;
00452   }
00453 
00454   void RegisterPtr(const SerializedPtrID& PtrID, const void* Ptr);
00455   
00456   void RegisterPtr(const void* Ptr) {
00457     RegisterPtr(ReadPtrID(),Ptr);
00458   }
00459   
00460   template<typename T>
00461   void RegisterRef(const T& x) {
00462     RegisterPtr(&x);
00463   }
00464   
00465   template<typename T>
00466   void RegisterRef(const SerializedPtrID& PtrID, const T& x) {
00467     RegisterPtr(PtrID,&x);
00468   }  
00469   
00470   Location getCurrentBlockLocation();
00471   unsigned getCurrentBlockID();
00472   unsigned getAbbrevNo();
00473   
00474   bool FinishedBlock(Location BlockLoc);
00475   bool JumpTo(const Location& BlockLoc);
00476   void Rewind();
00477   
00478   bool AtEnd();
00479   bool inRecord();
00480   void SkipBlock();
00481   bool SkipToBlock(unsigned BlockID);
00482   
00483   unsigned getRecordCode();
00484   
00485   BitstreamReader& getStream() { return Stream; }
00486   
00487 private:
00488   bool AdvanceStream();  
00489   void ReadRecord();
00490   
00491   uintptr_t ReadInternalRefPtr();
00492   
00493   static inline bool HasFinalPtr(MapTy::value_type& V) {
00494     return V.first.hasFinalPtr();
00495   }
00496   
00497   static inline uintptr_t GetFinalPtr(MapTy::value_type& V) {
00498     return reinterpret_cast<uintptr_t>(V.second.Ptr);
00499   }
00500   
00501   static inline BPNode* GetBPNode(MapTy::value_type& V) {
00502     return V.second.Head;
00503   }
00504     
00505   static inline void SetBPNode(MapTy::value_type& V, BPNode* N) {
00506     V.second.Head = N;
00507   }
00508   
00509   void SetPtr(MapTy::value_type& V, const void* P) {
00510     V.first.MarkFinal();
00511     V.second.SetPtr(FreeList,const_cast<void*>(P));
00512   }
00513 };
00514     
00515 } // end namespace llvm
00516 
00517 #endif