add a new MachineModuleInfoMachO class, which is the per-module
[llvm/avr.git] / lib / Bitcode / Reader / Deserialize.cpp
blob67607efae08a5e1f6376ca991279374890eea15f
1 //==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the internal methods used for object serialization.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Bitcode/Deserialize.h"
15 #include "llvm/Support/raw_ostream.h"
16 using namespace llvm;
18 Deserializer::Deserializer(BitstreamReader& stream)
19 : Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) {
21 StreamStart = Stream.GetCurrentBitNo();
24 Deserializer::~Deserializer() {
25 assert (RecIdx >= Record.size() &&
26 "Still scanning bitcode record when deserialization completed.");
28 #ifdef DEBUG_BACKPATCH
29 for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
30 assert (I->first.hasFinalPtr() &&
31 "Some pointers were not backpatched.");
32 #endif
36 bool Deserializer::inRecord() {
37 if (Record.size() > 0) {
38 if (RecIdx >= Record.size()) {
39 RecIdx = 0;
40 Record.clear();
41 AbbrevNo = 0;
42 return false;
44 else
45 return true;
48 return false;
51 bool Deserializer::AdvanceStream() {
52 assert (!inRecord() &&
53 "Cannot advance stream. Still processing a record.");
55 if (AbbrevNo == bitc::ENTER_SUBBLOCK ||
56 AbbrevNo >= bitc::UNABBREV_RECORD)
57 return true;
59 while (!Stream.AtEndOfStream()) {
61 uint64_t Pos = Stream.GetCurrentBitNo();
62 AbbrevNo = Stream.ReadCode();
64 switch (AbbrevNo) {
65 case bitc::ENTER_SUBBLOCK: {
66 unsigned id = Stream.ReadSubBlockID();
68 // Determine the extent of the block. This is useful for jumping around
69 // the stream. This is hack: we read the header of the block, save
70 // the length, and then revert the bitstream to a location just before
71 // the block is entered.
72 uint64_t BPos = Stream.GetCurrentBitNo();
73 Stream.ReadVBR(bitc::CodeLenWidth); // Skip the code size.
74 Stream.SkipToWord();
75 unsigned NumWords = Stream.Read(bitc::BlockSizeWidth);
76 Stream.JumpToBit(BPos);
78 BlockStack.push_back(Location(Pos,id,NumWords));
79 break;
82 case bitc::END_BLOCK: {
83 bool x = Stream.ReadBlockEnd();
84 assert(!x && "Error at block end."); x=x;
85 BlockStack.pop_back();
86 continue;
89 case bitc::DEFINE_ABBREV:
90 Stream.ReadAbbrevRecord();
91 continue;
93 default:
94 break;
97 return true;
100 return false;
103 void Deserializer::ReadRecord() {
105 while (AdvanceStream() && AbbrevNo == bitc::ENTER_SUBBLOCK) {
106 assert (!BlockStack.empty());
107 Stream.EnterSubBlock(BlockStack.back().BlockID);
108 AbbrevNo = 0;
111 if (Stream.AtEndOfStream())
112 return;
114 assert (Record.empty());
115 assert (AbbrevNo >= bitc::UNABBREV_RECORD);
116 RecordCode = Stream.ReadRecord(AbbrevNo,Record);
117 assert (Record.size() > 0);
120 void Deserializer::SkipBlock() {
121 assert (!inRecord());
123 if (AtEnd())
124 return;
126 AdvanceStream();
128 assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
129 BlockStack.pop_back();
130 Stream.SkipBlock();
132 AbbrevNo = 0;
133 AdvanceStream();
136 bool Deserializer::SkipToBlock(unsigned BlockID) {
137 assert (!inRecord());
139 AdvanceStream();
140 assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
142 unsigned BlockLevel = BlockStack.size();
144 while (!AtEnd() &&
145 BlockLevel == BlockStack.size() &&
146 getCurrentBlockID() != BlockID)
147 SkipBlock();
149 return !(AtEnd() || BlockLevel != BlockStack.size());
152 Deserializer::Location Deserializer::getCurrentBlockLocation() {
153 if (!inRecord())
154 AdvanceStream();
156 return BlockStack.back();
159 bool Deserializer::JumpTo(const Location& Loc) {
161 assert (!inRecord());
163 AdvanceStream();
165 assert (!BlockStack.empty() || AtEnd());
167 uint64_t LastBPos = StreamStart;
169 while (!BlockStack.empty()) {
171 LastBPos = BlockStack.back().BitNo;
173 // Determine of the current block contains the location of the block
174 // we are looking for.
175 if (BlockStack.back().contains(Loc)) {
176 // We found the enclosing block. We must first POP it off to
177 // destroy any accumulated context within the block scope. We then
178 // jump to the position of the block and enter it.
179 Stream.JumpToBit(LastBPos);
181 if (BlockStack.size() == Stream.BlockScope.size())
182 Stream.PopBlockScope();
184 BlockStack.pop_back();
186 AbbrevNo = 0;
187 AdvanceStream();
188 assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
190 Stream.EnterSubBlock(BlockStack.back().BlockID);
191 break;
194 // This block does not contain the block we are looking for. Pop it.
195 if (BlockStack.size() == Stream.BlockScope.size())
196 Stream.PopBlockScope();
198 BlockStack.pop_back();
202 // Check if we have popped our way to the outermost scope. If so,
203 // we need to adjust our position.
204 if (BlockStack.empty()) {
205 assert (Stream.BlockScope.empty());
207 Stream.JumpToBit(Loc.BitNo < LastBPos ? StreamStart : LastBPos);
208 AbbrevNo = 0;
209 AdvanceStream();
212 assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
213 assert (!BlockStack.empty());
215 while (!AtEnd() && BlockStack.back() != Loc) {
216 if (BlockStack.back().contains(Loc)) {
217 Stream.EnterSubBlock(BlockStack.back().BlockID);
218 AbbrevNo = 0;
219 AdvanceStream();
220 continue;
222 else
223 SkipBlock();
226 if (AtEnd())
227 return false;
229 assert (BlockStack.back() == Loc);
231 return true;
234 void Deserializer::Rewind() {
235 while (!Stream.BlockScope.empty())
236 Stream.PopBlockScope();
238 while (!BlockStack.empty())
239 BlockStack.pop_back();
241 Stream.JumpToBit(StreamStart);
242 AbbrevNo = 0;
246 unsigned Deserializer::getCurrentBlockID() {
247 if (!inRecord())
248 AdvanceStream();
250 return BlockStack.back().BlockID;
253 unsigned Deserializer::getRecordCode() {
254 if (!inRecord()) {
255 AdvanceStream();
256 assert (AbbrevNo >= bitc::UNABBREV_RECORD);
257 ReadRecord();
260 return RecordCode;
263 bool Deserializer::FinishedBlock(Location BlockLoc) {
264 if (!inRecord())
265 AdvanceStream();
267 for (llvm::SmallVector<Location,8>::reverse_iterator
268 I=BlockStack.rbegin(), E=BlockStack.rend(); I!=E; ++I)
269 if (*I == BlockLoc)
270 return false;
272 return true;
275 unsigned Deserializer::getAbbrevNo() {
276 if (!inRecord())
277 AdvanceStream();
279 return AbbrevNo;
282 bool Deserializer::AtEnd() {
283 if (inRecord())
284 return false;
286 if (!AdvanceStream())
287 return true;
289 return false;
292 uint64_t Deserializer::ReadInt() {
293 // FIXME: Any error recovery/handling with incomplete or bad files?
294 if (!inRecord())
295 ReadRecord();
297 return Record[RecIdx++];
300 int64_t Deserializer::ReadSInt() {
301 uint64_t x = ReadInt();
302 int64_t magnitude = x >> 1;
303 return x & 0x1 ? -magnitude : magnitude;
306 char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
307 if (cstr == NULL)
308 MaxLen = 0; // Zero this just in case someone does something funny.
310 unsigned len = ReadInt();
312 assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
314 if (!cstr)
315 cstr = new char[len + (isNullTerm ? 1 : 0)];
317 assert (cstr != NULL);
319 for (unsigned i = 0; i < len; ++i)
320 cstr[i] = (char) ReadInt();
322 if (isNullTerm)
323 cstr[len] = '\0';
325 return cstr;
328 void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm,
329 unsigned Idx) {
331 unsigned len = ReadInt();
333 // If Idx is beyond the current before size, reduce Idx to refer to the
334 // element after the last element.
335 if (Idx > buff.size())
336 Idx = buff.size();
338 buff.reserve(len+Idx);
339 buff.resize(Idx);
341 for (unsigned i = 0; i < len; ++i)
342 buff.push_back((char) ReadInt());
344 if (isNullTerm)
345 buff.push_back('\0');
348 void Deserializer::RegisterPtr(const SerializedPtrID& PtrId,
349 const void* Ptr) {
351 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
353 assert (!HasFinalPtr(E) && "Pointer already registered.");
355 #ifdef DEBUG_BACKPATCH
356 errs() << "RegisterPtr: " << PtrId << " => " << Ptr << "\n";
357 #endif
359 SetPtr(E,Ptr);
362 void Deserializer::ReadUIntPtr(uintptr_t& PtrRef,
363 const SerializedPtrID& PtrId,
364 bool AllowBackpatch) {
365 if (PtrId == 0) {
366 PtrRef = 0;
367 return;
370 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
372 if (HasFinalPtr(E)) {
373 PtrRef = GetFinalPtr(E);
375 #ifdef DEBUG_BACKPATCH
376 errs() << "ReadUintPtr: " << PtrId
377 << " <-- " << (void*) GetFinalPtr(E) << '\n';
378 #endif
380 else {
381 assert (AllowBackpatch &&
382 "Client forbids backpatching for this pointer.");
384 #ifdef DEBUG_BACKPATCH
385 errs() << "ReadUintPtr: " << PtrId << " (NO PTR YET)\n";
386 #endif
388 // Register backpatch. Check the freelist for a BPNode.
389 BPNode* N;
391 if (FreeList) {
392 N = FreeList;
393 FreeList = FreeList->Next;
395 else // No available BPNode. Allocate one.
396 N = (BPNode*) Allocator.Allocate<BPNode>();
398 new (N) BPNode(GetBPNode(E),PtrRef);
399 SetBPNode(E,N);
403 uintptr_t Deserializer::ReadInternalRefPtr() {
404 SerializedPtrID PtrId = ReadPtrID();
406 assert (PtrId != 0 && "References cannot refer the NULL address.");
408 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
410 assert (HasFinalPtr(E) &&
411 "Cannot backpatch references. Object must be already deserialized.");
413 return GetFinalPtr(E);
416 void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
417 BPNode* Last = NULL;
419 for (BPNode* N = Head; N != NULL; N=N->Next) {
420 Last = N;
421 N->PtrRef |= reinterpret_cast<uintptr_t>(P);
424 if (Last) {
425 Last->Next = FreeList;
426 FreeList = Head;
429 Ptr = const_cast<void*>(P);
433 #define INT_READ(TYPE)\
434 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
435 X = (TYPE) D.ReadInt(); }
437 INT_READ(bool)
438 INT_READ(unsigned char)
439 INT_READ(unsigned short)
440 INT_READ(unsigned int)
441 INT_READ(unsigned long)
443 #define SINT_READ(TYPE)\
444 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
445 X = (TYPE) D.ReadSInt(); }
447 INT_READ(signed char)
448 INT_READ(signed short)
449 INT_READ(signed int)
450 INT_READ(signed long)