//
// 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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
Deserializer::Deserializer(BitstreamReader& stream)
: Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) {
-
- AdvanceStream();
- if (!AtEnd()) StreamStart = BlockStack.back();
+
+ StreamStart = Stream.GetCurrentBitNo();
}
Deserializer::~Deserializer() {
case bitc::END_BLOCK: {
bool x = Stream.ReadBlockEnd();
- assert (!x && "Error at block end.");
+ assert(!x && "Error at block end."); x=x;
BlockStack.pop_back();
continue;
}
if (Stream.AtEndOfStream())
return;
- assert (Record.size() == 0);
+ assert (Record.empty());
assert (AbbrevNo >= bitc::UNABBREV_RECORD);
RecordCode = Stream.ReadRecord(AbbrevNo,Record);
assert (Record.size() > 0);
assert (!inRecord());
-// AdvanceStream();
+ AdvanceStream();
-// assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
- assert (!BlockStack.empty());
+ assert (!BlockStack.empty() || AtEnd());
- uint64_t LastBPos = StreamStart.BitNo;
+ uint64_t LastBPos = StreamStart;
while (!BlockStack.empty()) {
// destroy any accumulated context within the block scope. We then
// jump to the position of the block and enter it.
Stream.JumpToBit(LastBPos);
+
+ if (BlockStack.size() == Stream.BlockScope.size())
+ Stream.PopBlockScope();
+
BlockStack.pop_back();
- Stream.PopBlockScope();
AbbrevNo = 0;
AdvanceStream();
}
// This block does not contain the block we are looking for. Pop it.
+ if (BlockStack.size() == Stream.BlockScope.size())
+ Stream.PopBlockScope();
+
BlockStack.pop_back();
- Stream.PopBlockScope();
+
}
// Check if we have popped our way to the outermost scope. If so,
// we need to adjust our position.
if (BlockStack.empty()) {
- Stream.JumpToBit(Loc.BitNo < LastBPos ? StreamStart.BitNo : LastBPos);
+ assert (Stream.BlockScope.empty());
+
+ Stream.JumpToBit(Loc.BitNo < LastBPos ? StreamStart : LastBPos);
AbbrevNo = 0;
AdvanceStream();
}
return true;
}
+void Deserializer::Rewind() {
+ while (!Stream.BlockScope.empty())
+ Stream.PopBlockScope();
+
+ while (!BlockStack.empty())
+ BlockStack.pop_back();
+
+ Stream.JumpToBit(StreamStart);
+ AbbrevNo = 0;
+}
+
+
unsigned Deserializer::getCurrentBlockID() {
if (!inRecord())
AdvanceStream();
cstr[i] = (char) ReadInt();
if (isNullTerm)
- cstr[len+1] = '\0';
+ cstr[len] = '\0';
return cstr;
}
-void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
+void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm,
+ unsigned Idx) {
+
unsigned len = ReadInt();
- buff.clear();
- buff.reserve(len);
+ // If Idx is beyond the current before size, reduce Idx to refer to the
+ // element after the last element.
+ if (Idx > buff.size())
+ Idx = buff.size();
+
+ buff.reserve(len+Idx);
+ buff.resize(Idx);
for (unsigned i = 0; i < len; ++i)
buff.push_back((char) ReadInt());
buff.push_back('\0');
}
-void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
+void Deserializer::RegisterPtr(const SerializedPtrID& PtrId,
+ const void* Ptr) {
+
MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
assert (!HasFinalPtr(E) && "Pointer already registered.");
SetPtr(E,Ptr);
}
-void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) {
- SerializedPtrID PtrId = ReadPtrID();
-
+void Deserializer::ReadUIntPtr(uintptr_t& PtrRef,
+ const SerializedPtrID& PtrId,
+ bool AllowBackpatch) {
if (PtrId == 0) {
PtrRef = 0;
return;
}
-#ifdef DEBUG_BACKPATCH
- llvm::cerr << "ReadUintPtr: " << PtrId << "\n";
-#endif
-
MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
- if (HasFinalPtr(E))
+ if (HasFinalPtr(E)) {
PtrRef = GetFinalPtr(E);
+
+#ifdef DEBUG_BACKPATCH
+ llvm::cerr << "ReadUintPtr: " << PtrId
+ << " <-- " << (void*) GetFinalPtr(E) << '\n';
+#endif
+ }
else {
assert (AllowBackpatch &&
"Client forbids backpatching for this pointer.");
+#ifdef DEBUG_BACKPATCH
+ llvm::cerr << "ReadUintPtr: " << PtrId << " (NO PTR YET)\n";
+#endif
+
// Register backpatch. Check the freelist for a BPNode.
BPNode* N;