Updated Deserializer class to provide more information about the current
authorTed Kremenek <kremenek@apple.com>
Fri, 9 Nov 2007 00:43:51 +0000 (00:43 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 9 Nov 2007 00:43:51 +0000 (00:43 +0000)
block that is being visited in the bitstream.  The client can also now
skip blocks before reading them, and query the current abbreviation number
as seen from the perspective of the Deserializer.  This allows the client
to be more interactive in the deserialization process (if they so choose).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43916 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/Deserialize.h
lib/Bitcode/Reader/Deserialize.cpp

index c98b4e810a5bcd9e7718b5da37d485b8a5349b72..4ab35c04b1314b78feb8ad8a4a172d03b69e0634 100644 (file)
@@ -88,12 +88,14 @@ public:
 
 private:
   BitstreamReader& Stream;
-  SmallVector<uint64_t,10> Record;
+  SmallVector<uint64_t,20> Record;
   unsigned RecIdx;
   BumpPtrAllocator Allocator;
   BPNode* FreeList;
   MapTy BPatchMap;
-  llvm::SmallVector<uint64_t,5> BlockLocs;
+  llvm::SmallVector<std::pair<Location,unsigned>,5> BlockStack;
+  unsigned AbbrevNo;
+  unsigned RecordCode;
   
   //===----------------------------------------------------------===//
   // Public Interface.
@@ -231,14 +233,22 @@ public:
     RegisterPtr(PtrID,&x);
   }  
   
-  Location GetCurrentBlockLocation();
+  Location getCurrentBlockLocation();
+  unsigned getCurrentBlockID();
+  unsigned getAbbrevNo();
+  
   bool FinishedBlock(Location BlockLoc);
   
   bool AtEnd();
   bool inRecord();
+  void SkipBlock();
+  
+  unsigned getRecordCode();
   
 private:
-  void ReadRecord();  
+  bool AdvanceStream();  
+  void ReadRecord();
+  
   uintptr_t ReadInternalRefPtr();
   
   static inline bool HasFinalPtr(MapTy::value_type& V) {
index 5d0c724b8b9ab0b48b6bdcc2670e2b9035e4d8f4..012c815b435103e48a6afffcd7a1e7321d7b12e1 100644 (file)
 using namespace llvm;
 
 Deserializer::Deserializer(BitstreamReader& stream)
-  : Stream(stream), RecIdx(0), FreeList(NULL) {
+  : Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) {
 }
 
 Deserializer::~Deserializer() {
   assert (RecIdx >= Record.size() && 
           "Still scanning bitcode record when deserialization completed.");
  
-#ifdef NDEBUG
+#ifdef DEBUG_BACKPATCH
   for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
     assert (I->first.hasFinalPtr() &&
             "Some pointers were not backpatched.");
@@ -40,82 +40,131 @@ bool Deserializer::inRecord() {
     if (RecIdx >= Record.size()) {
       RecIdx = 0;
       Record.clear();
+      AbbrevNo = 0;
       return false;
     }
-    else return true;
+    else
+      return true;
   }
-  else return false;
-}
 
-void Deserializer::ReadRecord() {
-  // FIXME: Check if we haven't run off the edge of the stream.
-  // FIXME: Handle abbreviations.
+  return false;
+}
 
-  assert (Record.size() == 0);
+bool Deserializer::AdvanceStream() {
+  assert (!inRecord() && 
+          "Cannot advance stream.  Still processing a record.");
   
-  unsigned Code;
-
-  while (true) {
-    
-    if (Stream.AtEndOfStream())
-      return;
-    
-    Code = Stream.ReadCode();
+  if (AbbrevNo == bitc::ENTER_SUBBLOCK ||
+      AbbrevNo >= bitc::UNABBREV_RECORD)
+    return true;
   
-    if (Code == bitc::ENTER_SUBBLOCK) {
-      BlockLocs.push_back(Stream.GetCurrentBitNo());
-      unsigned id = Stream.ReadSubBlockID();
-      Stream.EnterSubBlock(id);
-      continue;
-    }
-
-    if (Code == bitc::END_BLOCK) {      
-      bool x = Stream.ReadBlockEnd();
-      assert (!x && "Error at block end.");
-      BlockLocs.pop_back();
-      continue;
-    }
+  while (!Stream.AtEndOfStream()) {
     
-    if (Code == bitc::DEFINE_ABBREV) {
-      Stream.ReadAbbrevRecord();
-      continue;
+    AbbrevNo = Stream.ReadCode();    
+  
+    switch (AbbrevNo) {        
+      case bitc::ENTER_SUBBLOCK: {
+        unsigned id = Stream.ReadSubBlockID();
+        BlockStack.push_back(std::make_pair(Stream.GetCurrentBitNo(),id));
+        break;
+      } 
+        
+      case bitc::END_BLOCK: {
+        bool x = Stream.ReadBlockEnd();
+        assert (!x && "Error at block end.");
+        BlockStack.pop_back();
+        continue;
+      }
+        
+      case bitc::DEFINE_ABBREV:
+        Stream.ReadAbbrevRecord();
+        continue;
+
+      default:
+        break;
     }
     
-    break;
+    return true;
   }
   
-  assert (Record.size() == 0);  
-  Stream.ReadRecord(Code,Record);  
-  assert (Record.size() > 0 || Stream.AtEndOfStream());
+  return false;
 }
 
-Deserializer::Location Deserializer::GetCurrentBlockLocation() {
+void Deserializer::ReadRecord() {
+  
+  while (AdvanceStream() && AbbrevNo == bitc::ENTER_SUBBLOCK) {
+    assert (!BlockStack.empty());
+    Stream.EnterSubBlock(BlockStack.back().second);
+    AbbrevNo = 0;
+  }
+
+  if (Stream.AtEndOfStream())
+    return;
+  
+  assert (Record.size() == 0);
+  assert (AbbrevNo >= bitc::UNABBREV_RECORD);
+  RecordCode = Stream.ReadRecord(AbbrevNo,Record);
+  assert (Record.size() > 0);
+}
+
+void Deserializer::SkipBlock() {
+  assert (!inRecord());
+  assert (AbbrevNo == bitc::ENTER_SUBBLOCK);  
+  Stream.SkipBlock();
+  AbbrevNo = 0;
+}
+
+Deserializer::Location Deserializer::getCurrentBlockLocation() {
   if (!inRecord())
-    ReadRecord();
+    AdvanceStream();
   
-  assert (!BlockLocs.empty());
-  return BlockLocs.back();
+  return BlockStack.back().first;
 }
 
-bool Deserializer::FinishedBlock(Location BlockLoc) {
+unsigned Deserializer::getCurrentBlockID() { 
   if (!inRecord())
+    AdvanceStream();
+  
+  return BlockStack.back().second;
+}
+
+unsigned Deserializer::getRecordCode() {
+  if (!inRecord()) {
+    AdvanceStream();
+    assert (AbbrevNo >= bitc::UNABBREV_RECORD);
     ReadRecord();
+  }
   
-  for (llvm::SmallVector<Location,5>::reverse_iterator
-       I=BlockLocs.rbegin(), E=BlockLocs.rend(); I!=E; ++I)
-    if (*I == BlockLoc)
-      return false;
+  return RecordCode;
+}
+
+bool Deserializer::FinishedBlock(Location BlockLoc) {
+  if (!inRecord())
+    AdvanceStream();
+
+  for (llvm::SmallVector<std::pair<Location,unsigned>,5>::reverse_iterator
+        I=BlockStack.rbegin(), E=BlockStack.rend(); I!=E; ++I)
+      if (I->first == BlockLoc)
+        return false;
   
   return true;
 }
 
+unsigned Deserializer::getAbbrevNo() {
+  if (!inRecord())
+    AdvanceStream();
+  
+  return AbbrevNo;
+}
+
 bool Deserializer::AtEnd() {
   if (inRecord())
     return false;
   
-  ReadRecord();
+  if (!AdvanceStream())
+    return true;
   
-  return Stream.AtEndOfStream();
+  return false;
 }
 
 uint64_t Deserializer::ReadInt() {