minor cleanups. Add provisions for a new standard BLOCKINFO_BLOCK
[oota-llvm.git] / include / llvm / Bitcode / BitstreamReader.h
index f41c4f0ec3b91ef3b31ffc4efa2dcc3f27ea2a90..eac9ab0b607ad82f5bdbca5cc4e4e6c5dd3d25e6 100644 (file)
@@ -48,9 +48,23 @@ class BitstreamReader {
   /// BlockScope - This tracks the codesize of parent blocks.
   SmallVector<Block, 8> BlockScope;
 
+  /// FirstChar - This remembers the first byte of the stream.
+  const unsigned char *FirstChar;
 public:
-  BitstreamReader(const unsigned char *Start, const unsigned char *End)
-    : NextChar(Start), LastChar(End) {
+  BitstreamReader() {
+    NextChar = FirstChar = LastChar = 0;
+    CurWord = 0;
+    BitsInCurWord = 0;
+    CurCodeSize = 0;
+  }
+
+  BitstreamReader(const unsigned char *Start, const unsigned char *End) {
+    init(Start, End);
+  }
+  
+  void init(const unsigned char *Start, const unsigned char *End) {
+    NextChar = FirstChar = Start;
+    LastChar = End;
     assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
     CurWord = 0;
     BitsInCurWord = 0;
@@ -61,12 +75,12 @@ public:
     // Abbrevs could still exist if the stream was broken.  If so, don't leak
     // them.
     for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
-      delete CurAbbrevs[i];
+      CurAbbrevs[i]->dropRef();
 
     for (unsigned S = 0, e = BlockScope.size(); S != e; ++S) {
       std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
       for (unsigned i = 0, e = Abbrevs.size(); i != e; ++i)
-        delete Abbrevs[i];
+        Abbrevs[i]->dropRef();
     }
   }
   
@@ -74,9 +88,28 @@ public:
   
   /// GetCurrentBitNo - Return the bit # of the bit we are reading.
   uint64_t GetCurrentBitNo() const {
-    return CurWord * 32ULL + (32-CurCodeSize);
+    return (NextChar-FirstChar)*8 + (32-BitsInCurWord);
+  }
+  
+  /// JumpToBit - Reset the stream to the specified bit number.
+  void JumpToBit(uint64_t BitNo) {
+    unsigned ByteNo = (BitNo/8) & ~3;
+    unsigned WordBitNo = BitNo & 31;
+    assert(ByteNo < (unsigned)(LastChar-FirstChar) && "Invalid location");
+    
+    // Move the cursor to the right word.
+    NextChar = FirstChar+ByteNo;
+    BitsInCurWord = 0;
+    
+    // Skip over any bits that are already consumed.
+    if (WordBitNo) {
+      NextChar -= 4;
+      Read(WordBitNo);
+    }
   }
   
+  /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
+  unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
   
   uint32_t Read(unsigned NumBits) {
     // If the field is fully contained by CurWord, return it quickly.
@@ -203,7 +236,7 @@ public:
   
   /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, read and enter
   /// the block, returning the BlockID of the block we just entered.
-  bool EnterSubBlock() {
+  bool EnterSubBlock(unsigned *NumWordsP = 0) {
     BlockScope.push_back(Block(CurCodeSize));
     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
     
@@ -211,6 +244,7 @@ public:
     CurCodeSize = ReadVBR(bitc::CodeLenWidth);
     SkipToWord();
     unsigned NumWords = Read(bitc::BlockSizeWidth);
+    if (NumWordsP) *NumWordsP = NumWords;
     
     // Validate that this block is sane.
     if (CurCodeSize == 0 || AtEndOfStream() || NextChar+NumWords*4 > LastChar)
@@ -229,7 +263,7 @@ public:
     
     // Delete abbrevs from popped scope.
     for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
-      delete CurAbbrevs[i];
+      CurAbbrevs[i]->dropRef();
     
     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
     BlockScope.pop_back();
@@ -249,7 +283,7 @@ public:
       return Code;
     }
     
-    unsigned AbbrevNo = AbbrevID-bitc::FIRST_ABBREV;
+    unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV;
     assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
     BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];