Add a new BitstreamEntry concept, and add two helper methods for walking
[oota-llvm.git] / lib / Bitcode / Reader / BitstreamReader.cpp
1 //===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Bitcode/BitstreamReader.h"
11
12 using namespace llvm;
13
14 //===----------------------------------------------------------------------===//
15 //  BitstreamCursor implementation
16 //===----------------------------------------------------------------------===//
17
18 void BitstreamCursor::operator=(const BitstreamCursor &RHS) {
19   freeState();
20   
21   BitStream = RHS.BitStream;
22   NextChar = RHS.NextChar;
23   CurWord = RHS.CurWord;
24   BitsInCurWord = RHS.BitsInCurWord;
25   CurCodeSize = RHS.CurCodeSize;
26   
27   // Copy abbreviations, and bump ref counts.
28   CurAbbrevs = RHS.CurAbbrevs;
29   for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
30        i != e; ++i)
31     CurAbbrevs[i]->addRef();
32   
33   // Copy block scope and bump ref counts.
34   BlockScope = RHS.BlockScope;
35   for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
36        S != e; ++S) {
37     std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
38     for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size());
39          i != e; ++i)
40       Abbrevs[i]->addRef();
41   }
42 }
43
44 void BitstreamCursor::freeState() {
45   // Free all the Abbrevs.
46   for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
47        i != e; ++i)
48     CurAbbrevs[i]->dropRef();
49   CurAbbrevs.clear();
50   
51   // Free all the Abbrevs in the block scope.
52   for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
53        S != e; ++S) {
54     std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
55     for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size());
56          i != e; ++i)
57       Abbrevs[i]->dropRef();
58   }
59   BlockScope.clear();
60 }
61
62 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
63 /// the block, and return true if the block has an error.
64 bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
65   // Save the current block's state on BlockScope.
66   BlockScope.push_back(Block(CurCodeSize));
67   BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
68   
69   // Add the abbrevs specific to this block to the CurAbbrevs list.
70   if (const BitstreamReader::BlockInfo *Info =
71       BitStream->getBlockInfo(BlockID)) {
72     for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
73          i != e; ++i) {
74       CurAbbrevs.push_back(Info->Abbrevs[i]);
75       CurAbbrevs.back()->addRef();
76     }
77   }
78   
79   // Get the codesize of this block.
80   CurCodeSize = ReadVBR(bitc::CodeLenWidth);
81   SkipToWord();
82   unsigned NumWords = Read(bitc::BlockSizeWidth);
83   if (NumWordsP) *NumWordsP = NumWords;
84   
85   // Validate that this block is sane.
86   if (CurCodeSize == 0 || AtEndOfStream())
87     return true;
88   
89   return false;
90 }
91
92
93 unsigned BitstreamCursor::ReadRecord(unsigned AbbrevID,
94                                      SmallVectorImpl<uint64_t> &Vals,
95                                      const char **BlobStart, unsigned *BlobLen){
96   if (AbbrevID == bitc::UNABBREV_RECORD) {
97     unsigned Code = ReadVBR(6);
98     unsigned NumElts = ReadVBR(6);
99     for (unsigned i = 0; i != NumElts; ++i)
100       Vals.push_back(ReadVBR64(6));
101     return Code;
102   }
103   
104   const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
105   
106   for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
107     const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
108     if (Op.isLiteral()) {
109       ReadAbbreviatedLiteral(Op, Vals);
110       continue;
111     }
112     
113     if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
114         Op.getEncoding() != BitCodeAbbrevOp::Blob) {
115       ReadAbbreviatedField(Op, Vals);
116       continue;
117     }
118     
119     if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
120       // Array case.  Read the number of elements as a vbr6.
121       unsigned NumElts = ReadVBR(6);
122       
123       // Get the element encoding.
124       assert(i+2 == e && "array op not second to last?");
125       const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
126       
127       // Read all the elements.
128       for (; NumElts; --NumElts)
129         ReadAbbreviatedField(EltEnc, Vals);
130       continue;
131     }
132     
133     assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
134     // Blob case.  Read the number of bytes as a vbr6.
135     unsigned NumElts = ReadVBR(6);
136     SkipToWord();  // 32-bit alignment
137     
138     // Figure out where the end of this blob will be including tail padding.
139     size_t NewEnd = NextChar+((NumElts+3)&~3);
140     
141     // If this would read off the end of the bitcode file, just set the
142     // record to empty and return.
143     if (!canSkipToPos(NewEnd)) {
144       Vals.append(NumElts, 0);
145       NextChar = BitStream->getBitcodeBytes().getExtent();
146       break;
147     }
148     
149     // Otherwise, read the number of bytes.  If we can return a reference to
150     // the data, do so to avoid copying it.
151     if (BlobStart) {
152       *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer(
153                                                             NextChar, NumElts);
154       *BlobLen = NumElts;
155     } else {
156       for (; NumElts; ++NextChar, --NumElts)
157         Vals.push_back(getByte(NextChar));
158     }
159     // Skip over tail padding.
160     NextChar = NewEnd;
161   }
162   
163   unsigned Code = (unsigned)Vals[0];
164   Vals.erase(Vals.begin());
165   return Code;
166 }
167
168
169 void BitstreamCursor::ReadAbbrevRecord() {
170   BitCodeAbbrev *Abbv = new BitCodeAbbrev();
171   unsigned NumOpInfo = ReadVBR(5);
172   for (unsigned i = 0; i != NumOpInfo; ++i) {
173     bool IsLiteral = Read(1) ? true : false;
174     if (IsLiteral) {
175       Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
176       continue;
177     }
178     
179     BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
180     if (BitCodeAbbrevOp::hasEncodingData(E))
181       Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5)));
182     else
183       Abbv->Add(BitCodeAbbrevOp(E));
184   }
185   CurAbbrevs.push_back(Abbv);
186 }
187
188 bool BitstreamCursor::ReadBlockInfoBlock() {
189   // If this is the second stream to get to the block info block, skip it.
190   if (BitStream->hasBlockInfoRecords())
191     return SkipBlock();
192   
193   if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
194   
195   SmallVector<uint64_t, 64> Record;
196   BitstreamReader::BlockInfo *CurBlockInfo = 0;
197   
198   // Read all the records for this module.
199   while (1) {
200     unsigned Code = ReadCode();
201     if (Code == bitc::END_BLOCK)
202       return ReadBlockEnd();
203     if (Code == bitc::ENTER_SUBBLOCK) {
204       ReadSubBlockID();
205       if (SkipBlock()) return true;
206       continue;
207     }
208     
209     // Read abbrev records, associate them with CurBID.
210     if (Code == bitc::DEFINE_ABBREV) {
211       if (!CurBlockInfo) return true;
212       ReadAbbrevRecord();
213       
214       // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
215       // appropriate BlockInfo.
216       BitCodeAbbrev *Abbv = CurAbbrevs.back();
217       CurAbbrevs.pop_back();
218       CurBlockInfo->Abbrevs.push_back(Abbv);
219       continue;
220     }
221     
222     // Read a record.
223     Record.clear();
224     switch (ReadRecord(Code, Record)) {
225       default: break;  // Default behavior, ignore unknown content.
226       case bitc::BLOCKINFO_CODE_SETBID:
227         if (Record.size() < 1) return true;
228         CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
229         break;
230       case bitc::BLOCKINFO_CODE_BLOCKNAME: {
231         if (!CurBlockInfo) return true;
232         if (BitStream->isIgnoringBlockInfoNames()) break;  // Ignore name.
233         std::string Name;
234         for (unsigned i = 0, e = Record.size(); i != e; ++i)
235           Name += (char)Record[i];
236         CurBlockInfo->Name = Name;
237         break;
238       }
239       case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
240         if (!CurBlockInfo) return true;
241         if (BitStream->isIgnoringBlockInfoNames()) break;  // Ignore name.
242         std::string Name;
243         for (unsigned i = 1, e = Record.size(); i != e; ++i)
244           Name += (char)Record[i];
245         CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
246                                                            Name));
247         break;
248       }
249     }
250   }
251 }
252
253