Switch the bitcode reader interface to take a MemoryBuffer instead of knowing
[oota-llvm.git] / include / llvm / Bitcode / BitstreamWriter.h
index 104508578d519d7a220e5394307dedebc59c7bc7..eaf2e4317c01452295fc13a3f87598524252355c 100644 (file)
@@ -32,7 +32,10 @@ class BitstreamWriter {
   // CurCodeSize - This is the declared size of code values used for the current
   // block, in bits.
   unsigned CurCodeSize;
-  
+
+  /// CurAbbrevs - Abbrevs installed at in this block.
+  std::vector<BitCodeAbbrev*> CurAbbrevs;
+
   struct Block {
     unsigned PrevCodeSize;
     unsigned StartSizeWord;
@@ -43,14 +46,13 @@ class BitstreamWriter {
   /// BlockScope - This tracks the current blocks that we have entered.
   std::vector<Block> BlockScope;
   
-  std::vector<BitCodeAbbrev*> CurAbbrevs;
 public:
   BitstreamWriter(std::vector<unsigned char> &O) 
     : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
 
   ~BitstreamWriter() {
     assert(CurBit == 0 && "Unflused data remaining");
-    assert(BlockScope.empty() && "Block imbalance");
+    assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
   }
   //===--------------------------------------------------------------------===//
   // Basic Primitives for emitting bits to the stream.
@@ -145,12 +147,8 @@ public:
     EmitVBR(CodeLen, bitc::CodeLenWidth);
     FlushToWord();
     BlockScope.push_back(Block(CurCodeSize, Out.size()/4));
-    
-    // Delete all abbrevs.
-    for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
-      delete CurAbbrevs[i];
-    
     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+    
     // Emit a placeholder, which will be replaced when the block is popped.
     Emit(0, bitc::BlockSizeWidth);
     
@@ -159,6 +157,11 @@ public:
   
   void ExitBlock() {
     assert(!BlockScope.empty() && "Block scope imbalance!");
+    
+    // Delete all abbrevs.
+    for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
+      delete CurAbbrevs[i];
+    
     const Block &B = BlockScope.back();
     
     // Block tail:
@@ -194,11 +197,40 @@ public:
       unsigned AbbrevNo = Abbrev-bitc::FIRST_ABBREV;
       assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
       BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
-      assert(0 && "TODO");
-      for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
-      }
       
+      EmitCode(Abbrev);
+      
+      // Insert the code into Vals to treat it uniformly.
+      Vals.insert(Vals.begin(), Code);
       
+      unsigned RecordIdx = 0;
+      for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+        assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+        const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+        uint64_t RecordVal = Vals[RecordIdx];
+        
+        if (Op.isLiteral()) {
+          // If the abbrev specifies the literal value to use, don't emit
+          // anything.
+          assert(RecordVal == Op.getLiteralValue() &&
+                 "Invalid abbrev for record!");
+          ++RecordIdx;
+        } else {
+          // Encode the value as we are commanded.
+          switch (Op.getEncoding()) {
+          default: assert(0 && "Unknown encoding!");
+          case BitCodeAbbrevOp::FixedWidth:
+            Emit64(RecordVal, Op.getEncodingData());
+            ++RecordIdx;
+            break;
+          case BitCodeAbbrevOp::VBR:
+            EmitVBR64(RecordVal, Op.getEncodingData());
+            ++RecordIdx;
+            break;
+          }
+        }
+      }
+      assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
     } else {
       // If we don't have an abbrev to use, emit this in its fully unabbreviated
       // form.
@@ -215,7 +247,43 @@ public:
   void EmitRecord(unsigned Code, SmallVectorImpl<unsigned> &Vals,
                   unsigned Abbrev = 0) {
     if (Abbrev) {
-      assert(0 && "abbrevs not implemented yet!");
+      unsigned AbbrevNo = Abbrev-bitc::FIRST_ABBREV;
+      assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+      BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
+      
+      EmitCode(Abbrev);
+
+      // Insert the code into Vals to treat it uniformly.
+      Vals.insert(Vals.begin(), Code);
+      
+      unsigned RecordIdx = 0;
+      for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+        assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+        const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+        unsigned RecordVal = Vals[RecordIdx];
+        
+        if (Op.isLiteral()) {
+          // If the abbrev specifies the literal value to use, don't emit
+          // anything.
+          assert(RecordVal == Op.getLiteralValue() &&
+                 "Invalid abbrev for record!");
+          ++RecordIdx;
+        } else {
+          // Encode the value as we are commanded.
+          switch (Op.getEncoding()) {
+          default: assert(0 && "Unknown encoding!");
+          case BitCodeAbbrevOp::FixedWidth:
+            Emit(RecordVal, Op.getEncodingData());
+            ++RecordIdx;
+            break;
+          case BitCodeAbbrevOp::VBR:
+            EmitVBR(RecordVal, Op.getEncodingData());
+            ++RecordIdx;
+            break;
+          }
+        }
+      }
+      assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
     } else {
       // If we don't have an abbrev to use, emit this in its fully unabbreviated
       // form.