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