Support for expanding the result of EXTRACT_ELEMENT.
[oota-llvm.git] / lib / Bitcode / Reader / Deserialize.cpp
index 965ff708a2c99393c5e43923f0ed1b9431f0265a..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.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -13,8 +13,6 @@
 
 #include "llvm/Bitcode/Deserialize.h"
 
-#define DEBUG_BACKPATCH
-
 #ifdef DEBUG_BACKPATCH
 #include "llvm/Support/Streams.h"
 #endif
@@ -23,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() {
@@ -88,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;
       }
@@ -118,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);
@@ -167,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()) {
     
@@ -185,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();      
@@ -197,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();
   }
@@ -231,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();
@@ -308,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());