llvm-6502/include/llvm/Bitcode/Deserialize.h
Ted Kremenek 48a396948f Updated Deserializer class to provide more information about the current
block that is being visited in the bitstream.  The client can also now
skip blocks before reading them, and query the current abbreviation number
as seen from the perspective of the Deserializer.  This allows the client
to be more interactive in the deserialization process (if they so choose).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43916 91177308-0d34-0410-b5e6-96231b3b80d8
2007-11-09 00:43:51 +00:00

279 lines
7.4 KiB
C++

//=- 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 "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm {
class Deserializer {
//===----------------------------------------------------------===//
// Internal type definitions.
//===----------------------------------------------------------===//
struct BPNode {
BPNode* Next;
uintptr_t& PtrRef;
BPNode(BPNode* n, uintptr_t& pref)
: Next(n), PtrRef(pref) {
PtrRef = 0;
}
};
struct BPEntry {
union { BPNode* Head; void* Ptr; };
BPEntry() : Head(NULL) {}
static inline bool isPod() { return true; }
void SetPtr(BPNode*& FreeList, void* P);
};
class BPKey {
unsigned Raw;
public:
BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
BPKey(unsigned code, unsigned) : Raw(code) {}
void MarkFinal() { Raw |= 0x1; }
bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
SerializedPtrID getID() const { return Raw >> 1; }
static inline BPKey getEmptyKey() { return BPKey(0,0); }
static inline BPKey getTombstoneKey() { return BPKey(1,0); }
static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
static bool isEqual(const BPKey& K1, const BPKey& K2) {
return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
}
static bool isPod() { return true; }
};
typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy;
//===----------------------------------------------------------===//
// Publicly visible types.
//===----------------------------------------------------------===//
public:
typedef uint64_t Location;
//===----------------------------------------------------------===//
// Internal data members.
//===----------------------------------------------------------===//
private:
BitstreamReader& Stream;
SmallVector<uint64_t,20> Record;
unsigned RecIdx;
BumpPtrAllocator Allocator;
BPNode* FreeList;
MapTy BPatchMap;
llvm::SmallVector<std::pair<Location,unsigned>,5> BlockStack;
unsigned AbbrevNo;
unsigned RecordCode;
//===----------------------------------------------------------===//
// Public Interface.
//===----------------------------------------------------------===//
public:
Deserializer(BitstreamReader& stream);
~Deserializer();
uint64_t ReadInt();
int64_t ReadSInt();
SerializedPtrID ReadPtrID() { return (SerializedPtrID) ReadInt(); }
bool ReadBool() {
return ReadInt() ? true : false;
}
template <typename T>
inline T& Read(T& X) {
SerializeTrait<T>::Read(*this,X);
return X;
}
template <typename T>
inline T* Materialize() {
return SerializeTrait<T>::Materialize(*this);
}
char* ReadCStr(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true);
void ReadCStr(std::vector<char>& buff, bool isNullTerm=false);
template <typename T>
inline T* ReadOwnedPtr(bool AutoRegister = true) {
SerializedPtrID PtrID = ReadPtrID();
if (!PtrID)
return NULL;
T* x = SerializeTrait<T>::Materialize(*this);
if (AutoRegister)
RegisterPtr(PtrID,x);
return x;
}
template <typename T>
inline void ReadOwnedPtr(T*& Ptr, bool AutoRegister = true) {
Ptr = ReadOwnedPtr<T>(AutoRegister);
}
template <typename T1, typename T2>
void BatchReadOwnedPtrs(T1*& P1, T2*& P2,
bool A1=true, bool A2=true) {
SerializedPtrID ID1 = ReadPtrID();
SerializedPtrID ID2 = ReadPtrID();
P1 = (ID1) ? SerializeTrait<T1>::Materialize(*this) : NULL;
if (ID1 && A1) RegisterPtr(ID1,P1);
P2 = (ID2) ? SerializeTrait<T2>::Materialize(*this) : NULL;
if (ID2 && A2) RegisterPtr(ID2,P2);
}
template <typename T1, typename T2, typename T3>
void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3,
bool A1=true, bool A2=true, bool A3=true) {
SerializedPtrID ID1 = ReadPtrID();
SerializedPtrID ID2 = ReadPtrID();
SerializedPtrID ID3 = ReadPtrID();
P1 = (ID1) ? SerializeTrait<T1>::Materialize(*this) : NULL;
if (ID1 && A1) RegisterPtr(ID1,P1);
P2 = (ID2) ? SerializeTrait<T2>::Materialize(*this) : NULL;
if (ID2 && A2) RegisterPtr(ID2,P2);
P3 = (ID3) ? SerializeTrait<T2>::Materialize(*this) : NULL;
if (ID3 && A3) RegisterPtr(ID3,P3);
}
template <typename T>
void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, bool AutoRegister=true) {
for (unsigned i = 0; i < NumPtrs; ++i)
reinterpret_cast<SerializedPtrID&>(Ptrs[i]) = ReadPtrID();
for (unsigned i = 0; i < NumPtrs; ++i) {
SerializedPtrID PtrID = reinterpret_cast<SerializedPtrID>(Ptrs[i]);
T* p = PtrID ? SerializeTrait<T>::Materialize(*this) : NULL;
if (PtrID && AutoRegister)
RegisterPtr(PtrID,p);
Ptrs[i] = p;
}
}
template <typename T>
void ReadPtr(T*& PtrRef, bool AllowBackpatch = true) {
ReadUIntPtr(reinterpret_cast<uintptr_t&>(PtrRef), AllowBackpatch);
}
template <typename T>
void ReadPtr(const T*& PtrRef, bool AllowBackpatch = true) {
ReadPtr(const_cast<T*&>(PtrRef), AllowBackpatch);
}
template <typename T>
T* ReadPtr() { T* x; ReadPtr<T>(x,false); return x; }
void ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch = true);
template <typename T>
T& ReadRef() {
T* p = reinterpret_cast<T*>(ReadInternalRefPtr());
return *p;
}
void RegisterPtr(SerializedPtrID PtrId, const void* Ptr);
void RegisterPtr(const void* Ptr) {
RegisterPtr(ReadPtrID(),Ptr);
}
template<typename T>
void RegisterRef(const T& x) {
RegisterPtr(&x);
}
template<typename T>
void RegisterRef(SerializedPtrID PtrID, const T& x) {
RegisterPtr(PtrID,&x);
}
Location getCurrentBlockLocation();
unsigned getCurrentBlockID();
unsigned getAbbrevNo();
bool FinishedBlock(Location BlockLoc);
bool AtEnd();
bool inRecord();
void SkipBlock();
unsigned getRecordCode();
private:
bool AdvanceStream();
void ReadRecord();
uintptr_t ReadInternalRefPtr();
static inline bool HasFinalPtr(MapTy::value_type& V) {
return V.first.hasFinalPtr();
}
static inline uintptr_t GetFinalPtr(MapTy::value_type& V) {
return reinterpret_cast<uintptr_t>(V.second.Ptr);
}
static inline BPNode* GetBPNode(MapTy::value_type& V) {
return V.second.Head;
}
static inline void SetBPNode(MapTy::value_type& V, BPNode* N) {
V.second.Head = N;
}
void SetPtr(MapTy::value_type& V, const void* P) {
V.first.MarkFinal();
V.second.SetPtr(FreeList,const_cast<void*>(P));
}
};
} // end namespace llvm
#endif