Support for expanding the result of EXTRACT_ELEMENT.
[oota-llvm.git] / lib / Bitcode / Reader / Deserialize.cpp
index 08ab02f698a3e610e912b9f51dcade11bc4095e8..2014557a1012da2755b6e2f0fda94a27dc3e4939 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     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.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -21,9 +21,8 @@ using namespace llvm;
 
 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() {
@@ -86,7 +85,7 @@ bool Deserializer::AdvanceStream() {
         
       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;
       }
@@ -116,7 +115,7 @@ void Deserializer::ReadRecord() {
   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);
@@ -165,12 +164,11 @@ bool Deserializer::JumpTo(const Location& Loc) {
     
   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()) {
     
@@ -183,8 +181,11 @@ bool Deserializer::JumpTo(const Location& Loc) {
       // 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();      
@@ -195,14 +196,19 @@ bool Deserializer::JumpTo(const Location& Loc) {
     }
 
     // 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();
   }
@@ -229,6 +235,18 @@ bool Deserializer::JumpTo(const Location& Loc) {
   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();
@@ -306,16 +324,23 @@ char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
     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());
@@ -324,7 +349,9 @@ void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
     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.");
@@ -336,26 +363,32 @@ void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
   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;