1e6d15924SDimitry Andric //===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
2e6d15924SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e6d15924SDimitry Andric //
7e6d15924SDimitry Andric //===----------------------------------------------------------------------===//
8e6d15924SDimitry Andric
9e6d15924SDimitry Andric #include "llvm/Bitstream/BitstreamReader.h"
10e6d15924SDimitry Andric #include "llvm/ADT/StringRef.h"
11e6d15924SDimitry Andric #include <cassert>
12e3b55780SDimitry Andric #include <optional>
13e6d15924SDimitry Andric #include <string>
14e6d15924SDimitry Andric
15e6d15924SDimitry Andric using namespace llvm;
16e6d15924SDimitry Andric
17e6d15924SDimitry Andric //===----------------------------------------------------------------------===//
18e6d15924SDimitry Andric // BitstreamCursor implementation
19e6d15924SDimitry Andric //===----------------------------------------------------------------------===//
20145449b1SDimitry Andric //
error(const char * Message)21145449b1SDimitry Andric static Error error(const char *Message) {
22145449b1SDimitry Andric return createStringError(std::errc::illegal_byte_sequence, Message);
23145449b1SDimitry Andric }
24e6d15924SDimitry Andric
25e6d15924SDimitry Andric /// Having read the ENTER_SUBBLOCK abbrevid, enter the block.
EnterSubBlock(unsigned BlockID,unsigned * NumWordsP)26e6d15924SDimitry Andric Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
27e6d15924SDimitry Andric // Save the current block's state on BlockScope.
28e6d15924SDimitry Andric BlockScope.push_back(Block(CurCodeSize));
29e6d15924SDimitry Andric BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
30e6d15924SDimitry Andric
31e6d15924SDimitry Andric // Add the abbrevs specific to this block to the CurAbbrevs list.
32e6d15924SDimitry Andric if (BlockInfo) {
33e6d15924SDimitry Andric if (const BitstreamBlockInfo::BlockInfo *Info =
34e6d15924SDimitry Andric BlockInfo->getBlockInfo(BlockID)) {
35b60736ecSDimitry Andric llvm::append_range(CurAbbrevs, Info->Abbrevs);
36e6d15924SDimitry Andric }
37e6d15924SDimitry Andric }
38e6d15924SDimitry Andric
39e6d15924SDimitry Andric // Get the codesize of this block.
40e6d15924SDimitry Andric Expected<uint32_t> MaybeVBR = ReadVBR(bitc::CodeLenWidth);
41e6d15924SDimitry Andric if (!MaybeVBR)
42e6d15924SDimitry Andric return MaybeVBR.takeError();
43e6d15924SDimitry Andric CurCodeSize = MaybeVBR.get();
44e6d15924SDimitry Andric
45e6d15924SDimitry Andric if (CurCodeSize > MaxChunkSize)
46e6d15924SDimitry Andric return llvm::createStringError(
47e6d15924SDimitry Andric std::errc::illegal_byte_sequence,
48e6d15924SDimitry Andric "can't read more than %zu at a time, trying to read %u", +MaxChunkSize,
49e6d15924SDimitry Andric CurCodeSize);
50e6d15924SDimitry Andric
51e6d15924SDimitry Andric SkipToFourByteBoundary();
52e6d15924SDimitry Andric Expected<word_t> MaybeNum = Read(bitc::BlockSizeWidth);
53e6d15924SDimitry Andric if (!MaybeNum)
54e6d15924SDimitry Andric return MaybeNum.takeError();
55e6d15924SDimitry Andric word_t NumWords = MaybeNum.get();
56e6d15924SDimitry Andric if (NumWordsP)
57e6d15924SDimitry Andric *NumWordsP = NumWords;
58e6d15924SDimitry Andric
59e6d15924SDimitry Andric if (CurCodeSize == 0)
60e6d15924SDimitry Andric return llvm::createStringError(
61e6d15924SDimitry Andric std::errc::illegal_byte_sequence,
62e6d15924SDimitry Andric "can't enter sub-block: current code size is 0");
63e6d15924SDimitry Andric if (AtEndOfStream())
64e6d15924SDimitry Andric return llvm::createStringError(
65e6d15924SDimitry Andric std::errc::illegal_byte_sequence,
66e6d15924SDimitry Andric "can't enter sub block: already at end of stream");
67e6d15924SDimitry Andric
68e6d15924SDimitry Andric return Error::success();
69e6d15924SDimitry Andric }
70e6d15924SDimitry Andric
readAbbreviatedField(BitstreamCursor & Cursor,const BitCodeAbbrevOp & Op)71e6d15924SDimitry Andric static Expected<uint64_t> readAbbreviatedField(BitstreamCursor &Cursor,
72e6d15924SDimitry Andric const BitCodeAbbrevOp &Op) {
73e6d15924SDimitry Andric assert(!Op.isLiteral() && "Not to be used with literals!");
74e6d15924SDimitry Andric
75e6d15924SDimitry Andric // Decode the value as we are commanded.
76e6d15924SDimitry Andric switch (Op.getEncoding()) {
77e6d15924SDimitry Andric case BitCodeAbbrevOp::Array:
78e6d15924SDimitry Andric case BitCodeAbbrevOp::Blob:
79e6d15924SDimitry Andric llvm_unreachable("Should not reach here");
80e6d15924SDimitry Andric case BitCodeAbbrevOp::Fixed:
81e6d15924SDimitry Andric assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
82e6d15924SDimitry Andric return Cursor.Read((unsigned)Op.getEncodingData());
83e6d15924SDimitry Andric case BitCodeAbbrevOp::VBR:
84e6d15924SDimitry Andric assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
85e6d15924SDimitry Andric return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
86e6d15924SDimitry Andric case BitCodeAbbrevOp::Char6:
87e6d15924SDimitry Andric if (Expected<unsigned> Res = Cursor.Read(6))
88e6d15924SDimitry Andric return BitCodeAbbrevOp::DecodeChar6(Res.get());
89e6d15924SDimitry Andric else
90e6d15924SDimitry Andric return Res.takeError();
91e6d15924SDimitry Andric }
92e6d15924SDimitry Andric llvm_unreachable("invalid abbreviation encoding");
93e6d15924SDimitry Andric }
94e6d15924SDimitry Andric
95e6d15924SDimitry Andric /// skipRecord - Read the current record and discard it.
skipRecord(unsigned AbbrevID)96e6d15924SDimitry Andric Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
97e6d15924SDimitry Andric // Skip unabbreviated records by reading past their entries.
98e6d15924SDimitry Andric if (AbbrevID == bitc::UNABBREV_RECORD) {
99e6d15924SDimitry Andric Expected<uint32_t> MaybeCode = ReadVBR(6);
100e6d15924SDimitry Andric if (!MaybeCode)
101e6d15924SDimitry Andric return MaybeCode.takeError();
102e6d15924SDimitry Andric unsigned Code = MaybeCode.get();
103e6d15924SDimitry Andric Expected<uint32_t> MaybeVBR = ReadVBR(6);
104e6d15924SDimitry Andric if (!MaybeVBR)
105145449b1SDimitry Andric return MaybeVBR.takeError();
106e6d15924SDimitry Andric unsigned NumElts = MaybeVBR.get();
107e6d15924SDimitry Andric for (unsigned i = 0; i != NumElts; ++i)
108e6d15924SDimitry Andric if (Expected<uint64_t> Res = ReadVBR64(6))
109e6d15924SDimitry Andric ; // Skip!
110e6d15924SDimitry Andric else
111e6d15924SDimitry Andric return Res.takeError();
112e6d15924SDimitry Andric return Code;
113e6d15924SDimitry Andric }
114e6d15924SDimitry Andric
115145449b1SDimitry Andric Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
116145449b1SDimitry Andric if (!MaybeAbbv)
117145449b1SDimitry Andric return MaybeAbbv.takeError();
118145449b1SDimitry Andric
119145449b1SDimitry Andric const BitCodeAbbrev *Abbv = MaybeAbbv.get();
120e6d15924SDimitry Andric const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
121e6d15924SDimitry Andric unsigned Code;
122e6d15924SDimitry Andric if (CodeOp.isLiteral())
123e6d15924SDimitry Andric Code = CodeOp.getLiteralValue();
124e6d15924SDimitry Andric else {
125e6d15924SDimitry Andric if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
126e6d15924SDimitry Andric CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
127e6d15924SDimitry Andric return llvm::createStringError(
128e6d15924SDimitry Andric std::errc::illegal_byte_sequence,
129e6d15924SDimitry Andric "Abbreviation starts with an Array or a Blob");
130e6d15924SDimitry Andric Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp);
131e6d15924SDimitry Andric if (!MaybeCode)
132e6d15924SDimitry Andric return MaybeCode.takeError();
133e6d15924SDimitry Andric Code = MaybeCode.get();
134e6d15924SDimitry Andric }
135e6d15924SDimitry Andric
136e6d15924SDimitry Andric for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i < e; ++i) {
137e6d15924SDimitry Andric const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
138e6d15924SDimitry Andric if (Op.isLiteral())
139e6d15924SDimitry Andric continue;
140e6d15924SDimitry Andric
141e6d15924SDimitry Andric if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
142e6d15924SDimitry Andric Op.getEncoding() != BitCodeAbbrevOp::Blob) {
143706b4fc4SDimitry Andric if (Expected<uint64_t> MaybeField = readAbbreviatedField(*this, Op))
144e6d15924SDimitry Andric continue;
145706b4fc4SDimitry Andric else
146706b4fc4SDimitry Andric return MaybeField.takeError();
147e6d15924SDimitry Andric }
148e6d15924SDimitry Andric
149e6d15924SDimitry Andric if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
150e6d15924SDimitry Andric // Array case. Read the number of elements as a vbr6.
151e6d15924SDimitry Andric Expected<uint32_t> MaybeNum = ReadVBR(6);
152e6d15924SDimitry Andric if (!MaybeNum)
153e6d15924SDimitry Andric return MaybeNum.takeError();
154e6d15924SDimitry Andric unsigned NumElts = MaybeNum.get();
155e6d15924SDimitry Andric
156e6d15924SDimitry Andric // Get the element encoding.
157e6d15924SDimitry Andric assert(i+2 == e && "array op not second to last?");
158e6d15924SDimitry Andric const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
159e6d15924SDimitry Andric
160e6d15924SDimitry Andric // Read all the elements.
161e6d15924SDimitry Andric // Decode the value as we are commanded.
162e6d15924SDimitry Andric switch (EltEnc.getEncoding()) {
163e6d15924SDimitry Andric default:
164145449b1SDimitry Andric return error("Array element type can't be an Array or a Blob");
165e6d15924SDimitry Andric case BitCodeAbbrevOp::Fixed:
166e6d15924SDimitry Andric assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
167b60736ecSDimitry Andric if (Error Err =
168b60736ecSDimitry Andric JumpToBit(GetCurrentBitNo() + static_cast<uint64_t>(NumElts) *
169b60736ecSDimitry Andric EltEnc.getEncodingData()))
170ac9a064cSDimitry Andric return Err;
171e6d15924SDimitry Andric break;
172e6d15924SDimitry Andric case BitCodeAbbrevOp::VBR:
173e6d15924SDimitry Andric assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
174e6d15924SDimitry Andric for (; NumElts; --NumElts)
175e6d15924SDimitry Andric if (Expected<uint64_t> Res =
176e6d15924SDimitry Andric ReadVBR64((unsigned)EltEnc.getEncodingData()))
177e6d15924SDimitry Andric ; // Skip!
178e6d15924SDimitry Andric else
179e6d15924SDimitry Andric return Res.takeError();
180e6d15924SDimitry Andric break;
181e6d15924SDimitry Andric case BitCodeAbbrevOp::Char6:
182e6d15924SDimitry Andric if (Error Err = JumpToBit(GetCurrentBitNo() + NumElts * 6))
183ac9a064cSDimitry Andric return Err;
184e6d15924SDimitry Andric break;
185e6d15924SDimitry Andric }
186e6d15924SDimitry Andric continue;
187e6d15924SDimitry Andric }
188e6d15924SDimitry Andric
189e6d15924SDimitry Andric assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
190e6d15924SDimitry Andric // Blob case. Read the number of bytes as a vbr6.
191e6d15924SDimitry Andric Expected<uint32_t> MaybeNum = ReadVBR(6);
192e6d15924SDimitry Andric if (!MaybeNum)
193e6d15924SDimitry Andric return MaybeNum.takeError();
194e6d15924SDimitry Andric unsigned NumElts = MaybeNum.get();
195e6d15924SDimitry Andric SkipToFourByteBoundary(); // 32-bit alignment
196e6d15924SDimitry Andric
197e6d15924SDimitry Andric // Figure out where the end of this blob will be including tail padding.
198b60736ecSDimitry Andric const size_t NewEnd = GetCurrentBitNo() + alignTo(NumElts, 4) * 8;
199e6d15924SDimitry Andric
200e6d15924SDimitry Andric // If this would read off the end of the bitcode file, just set the
201e6d15924SDimitry Andric // record to empty and return.
202e6d15924SDimitry Andric if (!canSkipToPos(NewEnd/8)) {
203e6d15924SDimitry Andric skipToEnd();
204e6d15924SDimitry Andric break;
205e6d15924SDimitry Andric }
206e6d15924SDimitry Andric
207e6d15924SDimitry Andric // Skip over the blob.
208e6d15924SDimitry Andric if (Error Err = JumpToBit(NewEnd))
209ac9a064cSDimitry Andric return Err;
210e6d15924SDimitry Andric }
211e6d15924SDimitry Andric return Code;
212e6d15924SDimitry Andric }
213e6d15924SDimitry Andric
readRecord(unsigned AbbrevID,SmallVectorImpl<uint64_t> & Vals,StringRef * Blob)214e6d15924SDimitry Andric Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
215e6d15924SDimitry Andric SmallVectorImpl<uint64_t> &Vals,
216e6d15924SDimitry Andric StringRef *Blob) {
217e6d15924SDimitry Andric if (AbbrevID == bitc::UNABBREV_RECORD) {
218e6d15924SDimitry Andric Expected<uint32_t> MaybeCode = ReadVBR(6);
219e6d15924SDimitry Andric if (!MaybeCode)
220e6d15924SDimitry Andric return MaybeCode.takeError();
221e6d15924SDimitry Andric uint32_t Code = MaybeCode.get();
222e6d15924SDimitry Andric Expected<uint32_t> MaybeNumElts = ReadVBR(6);
223e6d15924SDimitry Andric if (!MaybeNumElts)
224145449b1SDimitry Andric return error(
225145449b1SDimitry Andric ("Failed to read size: " + toString(MaybeNumElts.takeError()))
226145449b1SDimitry Andric .c_str());
227e6d15924SDimitry Andric uint32_t NumElts = MaybeNumElts.get();
228145449b1SDimitry Andric if (!isSizePlausible(NumElts))
229145449b1SDimitry Andric return error("Size is not plausible");
230cfca06d7SDimitry Andric Vals.reserve(Vals.size() + NumElts);
231e6d15924SDimitry Andric
232e6d15924SDimitry Andric for (unsigned i = 0; i != NumElts; ++i)
233e6d15924SDimitry Andric if (Expected<uint64_t> MaybeVal = ReadVBR64(6))
234e6d15924SDimitry Andric Vals.push_back(MaybeVal.get());
235e6d15924SDimitry Andric else
236e6d15924SDimitry Andric return MaybeVal.takeError();
237e6d15924SDimitry Andric return Code;
238e6d15924SDimitry Andric }
239e6d15924SDimitry Andric
240145449b1SDimitry Andric Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
241145449b1SDimitry Andric if (!MaybeAbbv)
242145449b1SDimitry Andric return MaybeAbbv.takeError();
243145449b1SDimitry Andric const BitCodeAbbrev *Abbv = MaybeAbbv.get();
244e6d15924SDimitry Andric
245e6d15924SDimitry Andric // Read the record code first.
246e6d15924SDimitry Andric assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
247e6d15924SDimitry Andric const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
248e6d15924SDimitry Andric unsigned Code;
249e6d15924SDimitry Andric if (CodeOp.isLiteral())
250e6d15924SDimitry Andric Code = CodeOp.getLiteralValue();
251e6d15924SDimitry Andric else {
252e6d15924SDimitry Andric if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
253e6d15924SDimitry Andric CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
254145449b1SDimitry Andric return error("Abbreviation starts with an Array or a Blob");
255e6d15924SDimitry Andric if (Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp))
256e6d15924SDimitry Andric Code = MaybeCode.get();
257e6d15924SDimitry Andric else
258e6d15924SDimitry Andric return MaybeCode.takeError();
259e6d15924SDimitry Andric }
260e6d15924SDimitry Andric
261e6d15924SDimitry Andric for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
262e6d15924SDimitry Andric const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
263e6d15924SDimitry Andric if (Op.isLiteral()) {
264e6d15924SDimitry Andric Vals.push_back(Op.getLiteralValue());
265e6d15924SDimitry Andric continue;
266e6d15924SDimitry Andric }
267e6d15924SDimitry Andric
268e6d15924SDimitry Andric if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
269e6d15924SDimitry Andric Op.getEncoding() != BitCodeAbbrevOp::Blob) {
270e6d15924SDimitry Andric if (Expected<uint64_t> MaybeVal = readAbbreviatedField(*this, Op))
271e6d15924SDimitry Andric Vals.push_back(MaybeVal.get());
272e6d15924SDimitry Andric else
273e6d15924SDimitry Andric return MaybeVal.takeError();
274e6d15924SDimitry Andric continue;
275e6d15924SDimitry Andric }
276e6d15924SDimitry Andric
277e6d15924SDimitry Andric if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
278e6d15924SDimitry Andric // Array case. Read the number of elements as a vbr6.
279e6d15924SDimitry Andric Expected<uint32_t> MaybeNumElts = ReadVBR(6);
280e6d15924SDimitry Andric if (!MaybeNumElts)
281145449b1SDimitry Andric return error(
282145449b1SDimitry Andric ("Failed to read size: " + toString(MaybeNumElts.takeError()))
283145449b1SDimitry Andric .c_str());
284e6d15924SDimitry Andric uint32_t NumElts = MaybeNumElts.get();
285145449b1SDimitry Andric if (!isSizePlausible(NumElts))
286145449b1SDimitry Andric return error("Size is not plausible");
287cfca06d7SDimitry Andric Vals.reserve(Vals.size() + NumElts);
288e6d15924SDimitry Andric
289e6d15924SDimitry Andric // Get the element encoding.
290e6d15924SDimitry Andric if (i + 2 != e)
291145449b1SDimitry Andric return error("Array op not second to last");
292e6d15924SDimitry Andric const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
293e6d15924SDimitry Andric if (!EltEnc.isEncoding())
294145449b1SDimitry Andric return error(
295e6d15924SDimitry Andric "Array element type has to be an encoding of a type");
296e6d15924SDimitry Andric
297e6d15924SDimitry Andric // Read all the elements.
298e6d15924SDimitry Andric switch (EltEnc.getEncoding()) {
299e6d15924SDimitry Andric default:
300145449b1SDimitry Andric return error("Array element type can't be an Array or a Blob");
301e6d15924SDimitry Andric case BitCodeAbbrevOp::Fixed:
302e6d15924SDimitry Andric for (; NumElts; --NumElts)
303e6d15924SDimitry Andric if (Expected<SimpleBitstreamCursor::word_t> MaybeVal =
304e6d15924SDimitry Andric Read((unsigned)EltEnc.getEncodingData()))
305e6d15924SDimitry Andric Vals.push_back(MaybeVal.get());
306e6d15924SDimitry Andric else
307e6d15924SDimitry Andric return MaybeVal.takeError();
308e6d15924SDimitry Andric break;
309e6d15924SDimitry Andric case BitCodeAbbrevOp::VBR:
310e6d15924SDimitry Andric for (; NumElts; --NumElts)
311e6d15924SDimitry Andric if (Expected<uint64_t> MaybeVal =
312e6d15924SDimitry Andric ReadVBR64((unsigned)EltEnc.getEncodingData()))
313e6d15924SDimitry Andric Vals.push_back(MaybeVal.get());
314e6d15924SDimitry Andric else
315e6d15924SDimitry Andric return MaybeVal.takeError();
316e6d15924SDimitry Andric break;
317e6d15924SDimitry Andric case BitCodeAbbrevOp::Char6:
318e6d15924SDimitry Andric for (; NumElts; --NumElts)
319e6d15924SDimitry Andric if (Expected<SimpleBitstreamCursor::word_t> MaybeVal = Read(6))
320e6d15924SDimitry Andric Vals.push_back(BitCodeAbbrevOp::DecodeChar6(MaybeVal.get()));
321e6d15924SDimitry Andric else
322e6d15924SDimitry Andric return MaybeVal.takeError();
323e6d15924SDimitry Andric }
324e6d15924SDimitry Andric continue;
325e6d15924SDimitry Andric }
326e6d15924SDimitry Andric
327e6d15924SDimitry Andric assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
328e6d15924SDimitry Andric // Blob case. Read the number of bytes as a vbr6.
329e6d15924SDimitry Andric Expected<uint32_t> MaybeNumElts = ReadVBR(6);
330e6d15924SDimitry Andric if (!MaybeNumElts)
331e6d15924SDimitry Andric return MaybeNumElts.takeError();
332e6d15924SDimitry Andric uint32_t NumElts = MaybeNumElts.get();
333e6d15924SDimitry Andric SkipToFourByteBoundary(); // 32-bit alignment
334e6d15924SDimitry Andric
335e6d15924SDimitry Andric // Figure out where the end of this blob will be including tail padding.
336e6d15924SDimitry Andric size_t CurBitPos = GetCurrentBitNo();
337b60736ecSDimitry Andric const size_t NewEnd = CurBitPos + alignTo(NumElts, 4) * 8;
338e6d15924SDimitry Andric
339145449b1SDimitry Andric // Make sure the bitstream is large enough to contain the blob.
340145449b1SDimitry Andric if (!canSkipToPos(NewEnd/8))
341145449b1SDimitry Andric return error("Blob ends too soon");
342e6d15924SDimitry Andric
343e6d15924SDimitry Andric // Otherwise, inform the streamer that we need these bytes in memory. Skip
344e6d15924SDimitry Andric // over tail padding first, in case jumping to NewEnd invalidates the Blob
345e6d15924SDimitry Andric // pointer.
346e6d15924SDimitry Andric if (Error Err = JumpToBit(NewEnd))
347ac9a064cSDimitry Andric return Err;
348e6d15924SDimitry Andric const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts);
349e6d15924SDimitry Andric
350e6d15924SDimitry Andric // If we can return a reference to the data, do so to avoid copying it.
351e6d15924SDimitry Andric if (Blob) {
352e6d15924SDimitry Andric *Blob = StringRef(Ptr, NumElts);
353e6d15924SDimitry Andric } else {
354e6d15924SDimitry Andric // Otherwise, unpack into Vals with zero extension.
355cfca06d7SDimitry Andric auto *UPtr = reinterpret_cast<const unsigned char *>(Ptr);
356cfca06d7SDimitry Andric Vals.append(UPtr, UPtr + NumElts);
357e6d15924SDimitry Andric }
358e6d15924SDimitry Andric }
359e6d15924SDimitry Andric
360e6d15924SDimitry Andric return Code;
361e6d15924SDimitry Andric }
362e6d15924SDimitry Andric
ReadAbbrevRecord()363e6d15924SDimitry Andric Error BitstreamCursor::ReadAbbrevRecord() {
364e6d15924SDimitry Andric auto Abbv = std::make_shared<BitCodeAbbrev>();
365e6d15924SDimitry Andric Expected<uint32_t> MaybeNumOpInfo = ReadVBR(5);
366e6d15924SDimitry Andric if (!MaybeNumOpInfo)
367e6d15924SDimitry Andric return MaybeNumOpInfo.takeError();
368e6d15924SDimitry Andric unsigned NumOpInfo = MaybeNumOpInfo.get();
369e6d15924SDimitry Andric for (unsigned i = 0; i != NumOpInfo; ++i) {
370e6d15924SDimitry Andric Expected<word_t> MaybeIsLiteral = Read(1);
371e6d15924SDimitry Andric if (!MaybeIsLiteral)
372e6d15924SDimitry Andric return MaybeIsLiteral.takeError();
373e6d15924SDimitry Andric bool IsLiteral = MaybeIsLiteral.get();
374e6d15924SDimitry Andric if (IsLiteral) {
375e6d15924SDimitry Andric Expected<uint64_t> MaybeOp = ReadVBR64(8);
376e6d15924SDimitry Andric if (!MaybeOp)
377e6d15924SDimitry Andric return MaybeOp.takeError();
378e6d15924SDimitry Andric Abbv->Add(BitCodeAbbrevOp(MaybeOp.get()));
379e6d15924SDimitry Andric continue;
380e6d15924SDimitry Andric }
381e6d15924SDimitry Andric
382e6d15924SDimitry Andric Expected<word_t> MaybeEncoding = Read(3);
383e6d15924SDimitry Andric if (!MaybeEncoding)
384e6d15924SDimitry Andric return MaybeEncoding.takeError();
385145449b1SDimitry Andric if (!BitCodeAbbrevOp::isValidEncoding(MaybeEncoding.get()))
386145449b1SDimitry Andric return error("Invalid encoding");
387145449b1SDimitry Andric
388e6d15924SDimitry Andric BitCodeAbbrevOp::Encoding E =
389e6d15924SDimitry Andric (BitCodeAbbrevOp::Encoding)MaybeEncoding.get();
390e6d15924SDimitry Andric if (BitCodeAbbrevOp::hasEncodingData(E)) {
391e6d15924SDimitry Andric Expected<uint64_t> MaybeData = ReadVBR64(5);
392e6d15924SDimitry Andric if (!MaybeData)
393e6d15924SDimitry Andric return MaybeData.takeError();
394e6d15924SDimitry Andric uint64_t Data = MaybeData.get();
395e6d15924SDimitry Andric
396e6d15924SDimitry Andric // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
397e6d15924SDimitry Andric // and vbr(0) as a literal zero. This is decoded the same way, and avoids
398e6d15924SDimitry Andric // a slow path in Read() to have to handle reading zero bits.
399e6d15924SDimitry Andric if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
400e6d15924SDimitry Andric Data == 0) {
401e6d15924SDimitry Andric Abbv->Add(BitCodeAbbrevOp(0));
402e6d15924SDimitry Andric continue;
403e6d15924SDimitry Andric }
404e6d15924SDimitry Andric
405e6d15924SDimitry Andric if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
406e6d15924SDimitry Andric Data > MaxChunkSize)
407145449b1SDimitry Andric return error("Fixed or VBR abbrev record with size > MaxChunkData");
408e6d15924SDimitry Andric
409e6d15924SDimitry Andric Abbv->Add(BitCodeAbbrevOp(E, Data));
410e6d15924SDimitry Andric } else
411e6d15924SDimitry Andric Abbv->Add(BitCodeAbbrevOp(E));
412e6d15924SDimitry Andric }
413e6d15924SDimitry Andric
414e6d15924SDimitry Andric if (Abbv->getNumOperandInfos() == 0)
415145449b1SDimitry Andric return error("Abbrev record with no operands");
416e6d15924SDimitry Andric CurAbbrevs.push_back(std::move(Abbv));
417e6d15924SDimitry Andric
418e6d15924SDimitry Andric return Error::success();
419e6d15924SDimitry Andric }
420e6d15924SDimitry Andric
421e3b55780SDimitry Andric Expected<std::optional<BitstreamBlockInfo>>
ReadBlockInfoBlock(bool ReadBlockInfoNames)422e6d15924SDimitry Andric BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) {
423e6d15924SDimitry Andric if (llvm::Error Err = EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID))
424ac9a064cSDimitry Andric return Err;
425e6d15924SDimitry Andric
426e6d15924SDimitry Andric BitstreamBlockInfo NewBlockInfo;
427e6d15924SDimitry Andric
428e6d15924SDimitry Andric SmallVector<uint64_t, 64> Record;
429e6d15924SDimitry Andric BitstreamBlockInfo::BlockInfo *CurBlockInfo = nullptr;
430e6d15924SDimitry Andric
431e6d15924SDimitry Andric // Read all the records for this module.
432e6d15924SDimitry Andric while (true) {
433e6d15924SDimitry Andric Expected<BitstreamEntry> MaybeEntry =
434e6d15924SDimitry Andric advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
435e6d15924SDimitry Andric if (!MaybeEntry)
436e6d15924SDimitry Andric return MaybeEntry.takeError();
437e6d15924SDimitry Andric BitstreamEntry Entry = MaybeEntry.get();
438e6d15924SDimitry Andric
439e6d15924SDimitry Andric switch (Entry.Kind) {
440e6d15924SDimitry Andric case llvm::BitstreamEntry::SubBlock: // Handled for us already.
441e6d15924SDimitry Andric case llvm::BitstreamEntry::Error:
442e3b55780SDimitry Andric return std::nullopt;
443e6d15924SDimitry Andric case llvm::BitstreamEntry::EndBlock:
444e6d15924SDimitry Andric return std::move(NewBlockInfo);
445e6d15924SDimitry Andric case llvm::BitstreamEntry::Record:
446e6d15924SDimitry Andric // The interesting case.
447e6d15924SDimitry Andric break;
448e6d15924SDimitry Andric }
449e6d15924SDimitry Andric
450e6d15924SDimitry Andric // Read abbrev records, associate them with CurBID.
451e6d15924SDimitry Andric if (Entry.ID == bitc::DEFINE_ABBREV) {
452e3b55780SDimitry Andric if (!CurBlockInfo)
453e3b55780SDimitry Andric return std::nullopt;
454e6d15924SDimitry Andric if (Error Err = ReadAbbrevRecord())
455ac9a064cSDimitry Andric return Err;
456e6d15924SDimitry Andric
457e6d15924SDimitry Andric // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
458e6d15924SDimitry Andric // appropriate BlockInfo.
459e6d15924SDimitry Andric CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
460e6d15924SDimitry Andric CurAbbrevs.pop_back();
461e6d15924SDimitry Andric continue;
462e6d15924SDimitry Andric }
463e6d15924SDimitry Andric
464e6d15924SDimitry Andric // Read a record.
465e6d15924SDimitry Andric Record.clear();
466e6d15924SDimitry Andric Expected<unsigned> MaybeBlockInfo = readRecord(Entry.ID, Record);
467e6d15924SDimitry Andric if (!MaybeBlockInfo)
468e6d15924SDimitry Andric return MaybeBlockInfo.takeError();
469e6d15924SDimitry Andric switch (MaybeBlockInfo.get()) {
470e6d15924SDimitry Andric default:
471e6d15924SDimitry Andric break; // Default behavior, ignore unknown content.
472e6d15924SDimitry Andric case bitc::BLOCKINFO_CODE_SETBID:
473e6d15924SDimitry Andric if (Record.size() < 1)
474e3b55780SDimitry Andric return std::nullopt;
475e6d15924SDimitry Andric CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]);
476e6d15924SDimitry Andric break;
477e6d15924SDimitry Andric case bitc::BLOCKINFO_CODE_BLOCKNAME: {
478e6d15924SDimitry Andric if (!CurBlockInfo)
479e3b55780SDimitry Andric return std::nullopt;
480e6d15924SDimitry Andric if (!ReadBlockInfoNames)
481e6d15924SDimitry Andric break; // Ignore name.
482cfca06d7SDimitry Andric CurBlockInfo->Name = std::string(Record.begin(), Record.end());
483e6d15924SDimitry Andric break;
484e6d15924SDimitry Andric }
485e6d15924SDimitry Andric case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
486e3b55780SDimitry Andric if (!CurBlockInfo)
487e3b55780SDimitry Andric return std::nullopt;
488e6d15924SDimitry Andric if (!ReadBlockInfoNames)
489e6d15924SDimitry Andric break; // Ignore name.
490cfca06d7SDimitry Andric CurBlockInfo->RecordNames.emplace_back(
491cfca06d7SDimitry Andric (unsigned)Record[0], std::string(Record.begin() + 1, Record.end()));
492e6d15924SDimitry Andric break;
493e6d15924SDimitry Andric }
494e6d15924SDimitry Andric }
495e6d15924SDimitry Andric }
496e6d15924SDimitry Andric }
497