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