1139f7f9bSDimitry Andric //===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
2139f7f9bSDimitry Andric //
3139f7f9bSDimitry Andric // The LLVM Compiler Infrastructure
4139f7f9bSDimitry Andric //
5139f7f9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
6139f7f9bSDimitry Andric // License. See LICENSE.TXT for details.
7139f7f9bSDimitry Andric //
8139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
9139f7f9bSDimitry Andric
10139f7f9bSDimitry Andric #include "llvm/Bitcode/BitstreamReader.h"
11d88c1a5aSDimitry Andric #include "llvm/ADT/StringRef.h"
12d88c1a5aSDimitry Andric #include <cassert>
13d88c1a5aSDimitry Andric #include <string>
14139f7f9bSDimitry Andric
15139f7f9bSDimitry Andric using namespace llvm;
16139f7f9bSDimitry Andric
17139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
18139f7f9bSDimitry Andric // BitstreamCursor implementation
19139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
20139f7f9bSDimitry Andric
21139f7f9bSDimitry Andric /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
22139f7f9bSDimitry Andric /// the block, and return true if the block has an error.
EnterSubBlock(unsigned BlockID,unsigned * NumWordsP)23139f7f9bSDimitry Andric bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
24139f7f9bSDimitry Andric // Save the current block's state on BlockScope.
25139f7f9bSDimitry Andric BlockScope.push_back(Block(CurCodeSize));
26139f7f9bSDimitry Andric BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
27139f7f9bSDimitry Andric
28139f7f9bSDimitry Andric // Add the abbrevs specific to this block to the CurAbbrevs list.
29d88c1a5aSDimitry Andric if (BlockInfo) {
30d88c1a5aSDimitry Andric if (const BitstreamBlockInfo::BlockInfo *Info =
31d88c1a5aSDimitry Andric BlockInfo->getBlockInfo(BlockID)) {
3239d628a0SDimitry Andric CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
3339d628a0SDimitry Andric Info->Abbrevs.end());
34139f7f9bSDimitry Andric }
35d88c1a5aSDimitry Andric }
36139f7f9bSDimitry Andric
37139f7f9bSDimitry Andric // Get the codesize of this block.
38139f7f9bSDimitry Andric CurCodeSize = ReadVBR(bitc::CodeLenWidth);
39ff0cc061SDimitry Andric // We can't read more than MaxChunkSize at a time
40ff0cc061SDimitry Andric if (CurCodeSize > MaxChunkSize)
41ff0cc061SDimitry Andric return true;
42ff0cc061SDimitry Andric
43139f7f9bSDimitry Andric SkipToFourByteBoundary();
44139f7f9bSDimitry Andric unsigned NumWords = Read(bitc::BlockSizeWidth);
45139f7f9bSDimitry Andric if (NumWordsP) *NumWordsP = NumWords;
46139f7f9bSDimitry Andric
47139f7f9bSDimitry Andric // Validate that this block is sane.
48ff0cc061SDimitry Andric return CurCodeSize == 0 || AtEndOfStream();
49139f7f9bSDimitry Andric }
50139f7f9bSDimitry Andric
readAbbreviatedField(BitstreamCursor & Cursor,const BitCodeAbbrevOp & Op)5139d628a0SDimitry Andric static uint64_t readAbbreviatedField(BitstreamCursor &Cursor,
5239d628a0SDimitry Andric const BitCodeAbbrevOp &Op) {
5339d628a0SDimitry Andric assert(!Op.isLiteral() && "Not to be used with literals!");
54139f7f9bSDimitry Andric
55139f7f9bSDimitry Andric // Decode the value as we are commanded.
56139f7f9bSDimitry Andric switch (Op.getEncoding()) {
57139f7f9bSDimitry Andric case BitCodeAbbrevOp::Array:
58139f7f9bSDimitry Andric case BitCodeAbbrevOp::Blob:
5991bc56edSDimitry Andric llvm_unreachable("Should not reach here");
60139f7f9bSDimitry Andric case BitCodeAbbrevOp::Fixed:
61ff0cc061SDimitry Andric assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
6239d628a0SDimitry Andric return Cursor.Read((unsigned)Op.getEncodingData());
63139f7f9bSDimitry Andric case BitCodeAbbrevOp::VBR:
64ff0cc061SDimitry Andric assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
6539d628a0SDimitry Andric return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
66139f7f9bSDimitry Andric case BitCodeAbbrevOp::Char6:
6739d628a0SDimitry Andric return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6));
68139f7f9bSDimitry Andric }
6939d628a0SDimitry Andric llvm_unreachable("invalid abbreviation encoding");
70139f7f9bSDimitry Andric }
71139f7f9bSDimitry Andric
skipAbbreviatedField(BitstreamCursor & Cursor,const BitCodeAbbrevOp & Op)7239d628a0SDimitry Andric static void skipAbbreviatedField(BitstreamCursor &Cursor,
7339d628a0SDimitry Andric const BitCodeAbbrevOp &Op) {
7439d628a0SDimitry Andric assert(!Op.isLiteral() && "Not to be used with literals!");
75139f7f9bSDimitry Andric
76139f7f9bSDimitry Andric // Decode the value as we are commanded.
77139f7f9bSDimitry Andric switch (Op.getEncoding()) {
78139f7f9bSDimitry Andric case BitCodeAbbrevOp::Array:
79139f7f9bSDimitry Andric case BitCodeAbbrevOp::Blob:
8091bc56edSDimitry Andric llvm_unreachable("Should not reach here");
81139f7f9bSDimitry Andric case BitCodeAbbrevOp::Fixed:
82ff0cc061SDimitry Andric assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
8339d628a0SDimitry Andric Cursor.Read((unsigned)Op.getEncodingData());
84139f7f9bSDimitry Andric break;
85139f7f9bSDimitry Andric case BitCodeAbbrevOp::VBR:
86ff0cc061SDimitry Andric assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
8739d628a0SDimitry Andric Cursor.ReadVBR64((unsigned)Op.getEncodingData());
88139f7f9bSDimitry Andric break;
89139f7f9bSDimitry Andric case BitCodeAbbrevOp::Char6:
9039d628a0SDimitry Andric Cursor.Read(6);
91139f7f9bSDimitry Andric break;
92139f7f9bSDimitry Andric }
93139f7f9bSDimitry Andric }
94139f7f9bSDimitry Andric
95139f7f9bSDimitry Andric /// skipRecord - Read the current record and discard it.
skipRecord(unsigned AbbrevID)96*95ec533aSDimitry Andric unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) {
97139f7f9bSDimitry Andric // Skip unabbreviated records by reading past their entries.
98139f7f9bSDimitry Andric if (AbbrevID == bitc::UNABBREV_RECORD) {
99139f7f9bSDimitry Andric unsigned Code = ReadVBR(6);
100139f7f9bSDimitry Andric unsigned NumElts = ReadVBR(6);
101139f7f9bSDimitry Andric for (unsigned i = 0; i != NumElts; ++i)
102139f7f9bSDimitry Andric (void)ReadVBR64(6);
103*95ec533aSDimitry Andric return Code;
104139f7f9bSDimitry Andric }
105139f7f9bSDimitry Andric
106139f7f9bSDimitry Andric const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
107*95ec533aSDimitry Andric const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
108*95ec533aSDimitry Andric unsigned Code;
109*95ec533aSDimitry Andric if (CodeOp.isLiteral())
110*95ec533aSDimitry Andric Code = CodeOp.getLiteralValue();
111*95ec533aSDimitry Andric else {
112*95ec533aSDimitry Andric if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
113*95ec533aSDimitry Andric CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
114*95ec533aSDimitry Andric report_fatal_error("Abbreviation starts with an Array or a Blob");
115*95ec533aSDimitry Andric Code = readAbbreviatedField(*this, CodeOp);
116*95ec533aSDimitry Andric }
117139f7f9bSDimitry Andric
118*95ec533aSDimitry Andric for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i < e; ++i) {
119139f7f9bSDimitry Andric const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
120139f7f9bSDimitry Andric if (Op.isLiteral())
121139f7f9bSDimitry Andric continue;
122139f7f9bSDimitry Andric
123139f7f9bSDimitry Andric if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
124139f7f9bSDimitry Andric Op.getEncoding() != BitCodeAbbrevOp::Blob) {
12539d628a0SDimitry Andric skipAbbreviatedField(*this, Op);
126139f7f9bSDimitry Andric continue;
127139f7f9bSDimitry Andric }
128139f7f9bSDimitry Andric
129139f7f9bSDimitry Andric if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
130139f7f9bSDimitry Andric // Array case. Read the number of elements as a vbr6.
131139f7f9bSDimitry Andric unsigned NumElts = ReadVBR(6);
132139f7f9bSDimitry Andric
133139f7f9bSDimitry Andric // Get the element encoding.
134139f7f9bSDimitry Andric assert(i+2 == e && "array op not second to last?");
135139f7f9bSDimitry Andric const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
136139f7f9bSDimitry Andric
137139f7f9bSDimitry Andric // Read all the elements.
1383ca95b02SDimitry Andric // Decode the value as we are commanded.
1393ca95b02SDimitry Andric switch (EltEnc.getEncoding()) {
1403ca95b02SDimitry Andric default:
1413ca95b02SDimitry Andric report_fatal_error("Array element type can't be an Array or a Blob");
1423ca95b02SDimitry Andric case BitCodeAbbrevOp::Fixed:
143d88c1a5aSDimitry Andric assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
144d88c1a5aSDimitry Andric JumpToBit(GetCurrentBitNo() + NumElts * EltEnc.getEncodingData());
1453ca95b02SDimitry Andric break;
1463ca95b02SDimitry Andric case BitCodeAbbrevOp::VBR:
147d88c1a5aSDimitry Andric assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
1483ca95b02SDimitry Andric for (; NumElts; --NumElts)
1493ca95b02SDimitry Andric ReadVBR64((unsigned)EltEnc.getEncodingData());
1503ca95b02SDimitry Andric break;
1513ca95b02SDimitry Andric case BitCodeAbbrevOp::Char6:
152d88c1a5aSDimitry Andric JumpToBit(GetCurrentBitNo() + NumElts * 6);
1533ca95b02SDimitry Andric break;
1543ca95b02SDimitry Andric }
155139f7f9bSDimitry Andric continue;
156139f7f9bSDimitry Andric }
157139f7f9bSDimitry Andric
158139f7f9bSDimitry Andric assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
159139f7f9bSDimitry Andric // Blob case. Read the number of bytes as a vbr6.
160139f7f9bSDimitry Andric unsigned NumElts = ReadVBR(6);
161139f7f9bSDimitry Andric SkipToFourByteBoundary(); // 32-bit alignment
162139f7f9bSDimitry Andric
163139f7f9bSDimitry Andric // Figure out where the end of this blob will be including tail padding.
164139f7f9bSDimitry Andric size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8;
165139f7f9bSDimitry Andric
166139f7f9bSDimitry Andric // If this would read off the end of the bitcode file, just set the
167139f7f9bSDimitry Andric // record to empty and return.
168139f7f9bSDimitry Andric if (!canSkipToPos(NewEnd/8)) {
1693ca95b02SDimitry Andric skipToEnd();
170139f7f9bSDimitry Andric break;
171139f7f9bSDimitry Andric }
172139f7f9bSDimitry Andric
173139f7f9bSDimitry Andric // Skip over the blob.
174139f7f9bSDimitry Andric JumpToBit(NewEnd);
175139f7f9bSDimitry Andric }
176*95ec533aSDimitry Andric return Code;
177139f7f9bSDimitry Andric }
178139f7f9bSDimitry Andric
readRecord(unsigned AbbrevID,SmallVectorImpl<uint64_t> & Vals,StringRef * Blob)179139f7f9bSDimitry Andric unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
180139f7f9bSDimitry Andric SmallVectorImpl<uint64_t> &Vals,
181139f7f9bSDimitry Andric StringRef *Blob) {
182139f7f9bSDimitry Andric if (AbbrevID == bitc::UNABBREV_RECORD) {
183139f7f9bSDimitry Andric unsigned Code = ReadVBR(6);
184139f7f9bSDimitry Andric unsigned NumElts = ReadVBR(6);
185139f7f9bSDimitry Andric for (unsigned i = 0; i != NumElts; ++i)
186139f7f9bSDimitry Andric Vals.push_back(ReadVBR64(6));
187139f7f9bSDimitry Andric return Code;
188139f7f9bSDimitry Andric }
189139f7f9bSDimitry Andric
190139f7f9bSDimitry Andric const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
191139f7f9bSDimitry Andric
192f785676fSDimitry Andric // Read the record code first.
193f785676fSDimitry Andric assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
194f785676fSDimitry Andric const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
19539d628a0SDimitry Andric unsigned Code;
196f785676fSDimitry Andric if (CodeOp.isLiteral())
19739d628a0SDimitry Andric Code = CodeOp.getLiteralValue();
198ff0cc061SDimitry Andric else {
199ff0cc061SDimitry Andric if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
200ff0cc061SDimitry Andric CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
201ff0cc061SDimitry Andric report_fatal_error("Abbreviation starts with an Array or a Blob");
20239d628a0SDimitry Andric Code = readAbbreviatedField(*this, CodeOp);
203ff0cc061SDimitry Andric }
204f785676fSDimitry Andric
205f785676fSDimitry Andric for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
206139f7f9bSDimitry Andric const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
207139f7f9bSDimitry Andric if (Op.isLiteral()) {
20839d628a0SDimitry Andric Vals.push_back(Op.getLiteralValue());
209139f7f9bSDimitry Andric continue;
210139f7f9bSDimitry Andric }
211139f7f9bSDimitry Andric
212139f7f9bSDimitry Andric if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
213139f7f9bSDimitry Andric Op.getEncoding() != BitCodeAbbrevOp::Blob) {
21439d628a0SDimitry Andric Vals.push_back(readAbbreviatedField(*this, Op));
215139f7f9bSDimitry Andric continue;
216139f7f9bSDimitry Andric }
217139f7f9bSDimitry Andric
218139f7f9bSDimitry Andric if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
219139f7f9bSDimitry Andric // Array case. Read the number of elements as a vbr6.
220139f7f9bSDimitry Andric unsigned NumElts = ReadVBR(6);
221139f7f9bSDimitry Andric
222139f7f9bSDimitry Andric // Get the element encoding.
223ff0cc061SDimitry Andric if (i + 2 != e)
224ff0cc061SDimitry Andric report_fatal_error("Array op not second to last");
225139f7f9bSDimitry Andric const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
226ff0cc061SDimitry Andric if (!EltEnc.isEncoding())
227ff0cc061SDimitry Andric report_fatal_error(
228ff0cc061SDimitry Andric "Array element type has to be an encoding of a type");
229139f7f9bSDimitry Andric
230139f7f9bSDimitry Andric // Read all the elements.
2313ca95b02SDimitry Andric switch (EltEnc.getEncoding()) {
2323ca95b02SDimitry Andric default:
2333ca95b02SDimitry Andric report_fatal_error("Array element type can't be an Array or a Blob");
2343ca95b02SDimitry Andric case BitCodeAbbrevOp::Fixed:
235139f7f9bSDimitry Andric for (; NumElts; --NumElts)
2363ca95b02SDimitry Andric Vals.push_back(Read((unsigned)EltEnc.getEncodingData()));
2373ca95b02SDimitry Andric break;
2383ca95b02SDimitry Andric case BitCodeAbbrevOp::VBR:
2393ca95b02SDimitry Andric for (; NumElts; --NumElts)
2403ca95b02SDimitry Andric Vals.push_back(ReadVBR64((unsigned)EltEnc.getEncodingData()));
2413ca95b02SDimitry Andric break;
2423ca95b02SDimitry Andric case BitCodeAbbrevOp::Char6:
2433ca95b02SDimitry Andric for (; NumElts; --NumElts)
2443ca95b02SDimitry Andric Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
2453ca95b02SDimitry Andric }
246139f7f9bSDimitry Andric continue;
247139f7f9bSDimitry Andric }
248139f7f9bSDimitry Andric
249139f7f9bSDimitry Andric assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
250139f7f9bSDimitry Andric // Blob case. Read the number of bytes as a vbr6.
251139f7f9bSDimitry Andric unsigned NumElts = ReadVBR(6);
252139f7f9bSDimitry Andric SkipToFourByteBoundary(); // 32-bit alignment
253139f7f9bSDimitry Andric
254139f7f9bSDimitry Andric // Figure out where the end of this blob will be including tail padding.
255139f7f9bSDimitry Andric size_t CurBitPos = GetCurrentBitNo();
256139f7f9bSDimitry Andric size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8;
257139f7f9bSDimitry Andric
258139f7f9bSDimitry Andric // If this would read off the end of the bitcode file, just set the
259139f7f9bSDimitry Andric // record to empty and return.
260139f7f9bSDimitry Andric if (!canSkipToPos(NewEnd/8)) {
261139f7f9bSDimitry Andric Vals.append(NumElts, 0);
2623ca95b02SDimitry Andric skipToEnd();
263139f7f9bSDimitry Andric break;
264139f7f9bSDimitry Andric }
265139f7f9bSDimitry Andric
2663ca95b02SDimitry Andric // Otherwise, inform the streamer that we need these bytes in memory. Skip
2673ca95b02SDimitry Andric // over tail padding first, in case jumping to NewEnd invalidates the Blob
2683ca95b02SDimitry Andric // pointer.
2693ca95b02SDimitry Andric JumpToBit(NewEnd);
2703ca95b02SDimitry Andric const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts);
271139f7f9bSDimitry Andric
272139f7f9bSDimitry Andric // If we can return a reference to the data, do so to avoid copying it.
273139f7f9bSDimitry Andric if (Blob) {
274139f7f9bSDimitry Andric *Blob = StringRef(Ptr, NumElts);
275139f7f9bSDimitry Andric } else {
276139f7f9bSDimitry Andric // Otherwise, unpack into Vals with zero extension.
277139f7f9bSDimitry Andric for (; NumElts; --NumElts)
278139f7f9bSDimitry Andric Vals.push_back((unsigned char)*Ptr++);
279139f7f9bSDimitry Andric }
280139f7f9bSDimitry Andric }
281139f7f9bSDimitry Andric
282139f7f9bSDimitry Andric return Code;
283139f7f9bSDimitry Andric }
284139f7f9bSDimitry Andric
ReadAbbrevRecord()285139f7f9bSDimitry Andric void BitstreamCursor::ReadAbbrevRecord() {
286*95ec533aSDimitry Andric auto Abbv = std::make_shared<BitCodeAbbrev>();
287139f7f9bSDimitry Andric unsigned NumOpInfo = ReadVBR(5);
288139f7f9bSDimitry Andric for (unsigned i = 0; i != NumOpInfo; ++i) {
289ff0cc061SDimitry Andric bool IsLiteral = Read(1);
290139f7f9bSDimitry Andric if (IsLiteral) {
291139f7f9bSDimitry Andric Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
292139f7f9bSDimitry Andric continue;
293139f7f9bSDimitry Andric }
294139f7f9bSDimitry Andric
295139f7f9bSDimitry Andric BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
296139f7f9bSDimitry Andric if (BitCodeAbbrevOp::hasEncodingData(E)) {
297ff0cc061SDimitry Andric uint64_t Data = ReadVBR64(5);
298139f7f9bSDimitry Andric
299139f7f9bSDimitry Andric // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
300139f7f9bSDimitry Andric // and vbr(0) as a literal zero. This is decoded the same way, and avoids
301139f7f9bSDimitry Andric // a slow path in Read() to have to handle reading zero bits.
302139f7f9bSDimitry Andric if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
303139f7f9bSDimitry Andric Data == 0) {
304139f7f9bSDimitry Andric Abbv->Add(BitCodeAbbrevOp(0));
305139f7f9bSDimitry Andric continue;
306139f7f9bSDimitry Andric }
307139f7f9bSDimitry Andric
308ff0cc061SDimitry Andric if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
309ff0cc061SDimitry Andric Data > MaxChunkSize)
310ff0cc061SDimitry Andric report_fatal_error(
311ff0cc061SDimitry Andric "Fixed or VBR abbrev record with size > MaxChunkData");
312ff0cc061SDimitry Andric
313139f7f9bSDimitry Andric Abbv->Add(BitCodeAbbrevOp(E, Data));
314139f7f9bSDimitry Andric } else
315139f7f9bSDimitry Andric Abbv->Add(BitCodeAbbrevOp(E));
316139f7f9bSDimitry Andric }
317ff0cc061SDimitry Andric
318ff0cc061SDimitry Andric if (Abbv->getNumOperandInfos() == 0)
319ff0cc061SDimitry Andric report_fatal_error("Abbrev record with no operands");
320*95ec533aSDimitry Andric CurAbbrevs.push_back(std::move(Abbv));
321139f7f9bSDimitry Andric }
322139f7f9bSDimitry Andric
323d88c1a5aSDimitry Andric Optional<BitstreamBlockInfo>
ReadBlockInfoBlock(bool ReadBlockInfoNames)324d88c1a5aSDimitry Andric BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) {
325d88c1a5aSDimitry Andric if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return None;
326139f7f9bSDimitry Andric
327d88c1a5aSDimitry Andric BitstreamBlockInfo NewBlockInfo;
328139f7f9bSDimitry Andric
329139f7f9bSDimitry Andric SmallVector<uint64_t, 64> Record;
330d88c1a5aSDimitry Andric BitstreamBlockInfo::BlockInfo *CurBlockInfo = nullptr;
331139f7f9bSDimitry Andric
332139f7f9bSDimitry Andric // Read all the records for this module.
333d88c1a5aSDimitry Andric while (true) {
334139f7f9bSDimitry Andric BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
335139f7f9bSDimitry Andric
336139f7f9bSDimitry Andric switch (Entry.Kind) {
337139f7f9bSDimitry Andric case llvm::BitstreamEntry::SubBlock: // Handled for us already.
338139f7f9bSDimitry Andric case llvm::BitstreamEntry::Error:
339d88c1a5aSDimitry Andric return None;
340139f7f9bSDimitry Andric case llvm::BitstreamEntry::EndBlock:
341d88c1a5aSDimitry Andric return std::move(NewBlockInfo);
342139f7f9bSDimitry Andric case llvm::BitstreamEntry::Record:
343139f7f9bSDimitry Andric // The interesting case.
344139f7f9bSDimitry Andric break;
345139f7f9bSDimitry Andric }
346139f7f9bSDimitry Andric
347139f7f9bSDimitry Andric // Read abbrev records, associate them with CurBID.
348139f7f9bSDimitry Andric if (Entry.ID == bitc::DEFINE_ABBREV) {
349d88c1a5aSDimitry Andric if (!CurBlockInfo) return None;
350139f7f9bSDimitry Andric ReadAbbrevRecord();
351139f7f9bSDimitry Andric
352139f7f9bSDimitry Andric // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
353139f7f9bSDimitry Andric // appropriate BlockInfo.
35439d628a0SDimitry Andric CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
355139f7f9bSDimitry Andric CurAbbrevs.pop_back();
356139f7f9bSDimitry Andric continue;
357139f7f9bSDimitry Andric }
358139f7f9bSDimitry Andric
359139f7f9bSDimitry Andric // Read a record.
360139f7f9bSDimitry Andric Record.clear();
361139f7f9bSDimitry Andric switch (readRecord(Entry.ID, Record)) {
362139f7f9bSDimitry Andric default: break; // Default behavior, ignore unknown content.
363139f7f9bSDimitry Andric case bitc::BLOCKINFO_CODE_SETBID:
364d88c1a5aSDimitry Andric if (Record.size() < 1) return None;
365d88c1a5aSDimitry Andric CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]);
366139f7f9bSDimitry Andric break;
367139f7f9bSDimitry Andric case bitc::BLOCKINFO_CODE_BLOCKNAME: {
368d88c1a5aSDimitry Andric if (!CurBlockInfo) return None;
369d88c1a5aSDimitry Andric if (!ReadBlockInfoNames)
3703ca95b02SDimitry Andric break; // Ignore name.
371139f7f9bSDimitry Andric std::string Name;
372139f7f9bSDimitry Andric for (unsigned i = 0, e = Record.size(); i != e; ++i)
373139f7f9bSDimitry Andric Name += (char)Record[i];
374139f7f9bSDimitry Andric CurBlockInfo->Name = Name;
375139f7f9bSDimitry Andric break;
376139f7f9bSDimitry Andric }
377139f7f9bSDimitry Andric case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
378d88c1a5aSDimitry Andric if (!CurBlockInfo) return None;
379d88c1a5aSDimitry Andric if (!ReadBlockInfoNames)
3803ca95b02SDimitry Andric break; // Ignore name.
381139f7f9bSDimitry Andric std::string Name;
382139f7f9bSDimitry Andric for (unsigned i = 1, e = Record.size(); i != e; ++i)
383139f7f9bSDimitry Andric Name += (char)Record[i];
384139f7f9bSDimitry Andric CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
385139f7f9bSDimitry Andric Name));
386139f7f9bSDimitry Andric break;
387139f7f9bSDimitry Andric }
388139f7f9bSDimitry Andric }
389139f7f9bSDimitry Andric }
390139f7f9bSDimitry Andric }
391