xref: /freebsd-src/contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/Bitstream/BitstreamReader.h"
100b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
110b57cec5SDimitry Andric #include <cassert>
12bdd1243dSDimitry Andric #include <optional>
130b57cec5SDimitry Andric #include <string>
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric using namespace llvm;
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
180b57cec5SDimitry Andric //  BitstreamCursor implementation
190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2081ad6265SDimitry Andric //
2181ad6265SDimitry Andric static Error error(const char *Message) {
2281ad6265SDimitry Andric   return createStringError(std::errc::illegal_byte_sequence, Message);
2381ad6265SDimitry Andric }
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric /// Having read the ENTER_SUBBLOCK abbrevid, enter the block.
260b57cec5SDimitry Andric Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
270b57cec5SDimitry Andric   // Save the current block's state on BlockScope.
280b57cec5SDimitry Andric   BlockScope.push_back(Block(CurCodeSize));
290b57cec5SDimitry Andric   BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric   // Add the abbrevs specific to this block to the CurAbbrevs list.
320b57cec5SDimitry Andric   if (BlockInfo) {
330b57cec5SDimitry Andric     if (const BitstreamBlockInfo::BlockInfo *Info =
340b57cec5SDimitry Andric             BlockInfo->getBlockInfo(BlockID)) {
35e8d8bef9SDimitry Andric       llvm::append_range(CurAbbrevs, Info->Abbrevs);
360b57cec5SDimitry Andric     }
370b57cec5SDimitry Andric   }
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   // Get the codesize of this block.
400b57cec5SDimitry Andric   Expected<uint32_t> MaybeVBR = ReadVBR(bitc::CodeLenWidth);
410b57cec5SDimitry Andric   if (!MaybeVBR)
420b57cec5SDimitry Andric     return MaybeVBR.takeError();
430b57cec5SDimitry Andric   CurCodeSize = MaybeVBR.get();
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   if (CurCodeSize > MaxChunkSize)
460b57cec5SDimitry Andric     return llvm::createStringError(
470b57cec5SDimitry Andric         std::errc::illegal_byte_sequence,
480b57cec5SDimitry Andric         "can't read more than %zu at a time, trying to read %u", +MaxChunkSize,
490b57cec5SDimitry Andric         CurCodeSize);
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   SkipToFourByteBoundary();
520b57cec5SDimitry Andric   Expected<word_t> MaybeNum = Read(bitc::BlockSizeWidth);
530b57cec5SDimitry Andric   if (!MaybeNum)
540b57cec5SDimitry Andric     return MaybeNum.takeError();
550b57cec5SDimitry Andric   word_t NumWords = MaybeNum.get();
560b57cec5SDimitry Andric   if (NumWordsP)
570b57cec5SDimitry Andric     *NumWordsP = NumWords;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   if (CurCodeSize == 0)
600b57cec5SDimitry Andric     return llvm::createStringError(
610b57cec5SDimitry Andric         std::errc::illegal_byte_sequence,
620b57cec5SDimitry Andric         "can't enter sub-block: current code size is 0");
630b57cec5SDimitry Andric   if (AtEndOfStream())
640b57cec5SDimitry Andric     return llvm::createStringError(
650b57cec5SDimitry Andric         std::errc::illegal_byte_sequence,
660b57cec5SDimitry Andric         "can't enter sub block: already at end of stream");
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   return Error::success();
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric static Expected<uint64_t> readAbbreviatedField(BitstreamCursor &Cursor,
720b57cec5SDimitry Andric                                                const BitCodeAbbrevOp &Op) {
730b57cec5SDimitry Andric   assert(!Op.isLiteral() && "Not to be used with literals!");
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   // Decode the value as we are commanded.
760b57cec5SDimitry Andric   switch (Op.getEncoding()) {
770b57cec5SDimitry Andric   case BitCodeAbbrevOp::Array:
780b57cec5SDimitry Andric   case BitCodeAbbrevOp::Blob:
790b57cec5SDimitry Andric     llvm_unreachable("Should not reach here");
800b57cec5SDimitry Andric   case BitCodeAbbrevOp::Fixed:
810b57cec5SDimitry Andric     assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
820b57cec5SDimitry Andric     return Cursor.Read((unsigned)Op.getEncodingData());
830b57cec5SDimitry Andric   case BitCodeAbbrevOp::VBR:
840b57cec5SDimitry Andric     assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
850b57cec5SDimitry Andric     return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
860b57cec5SDimitry Andric   case BitCodeAbbrevOp::Char6:
870b57cec5SDimitry Andric     if (Expected<unsigned> Res = Cursor.Read(6))
880b57cec5SDimitry Andric       return BitCodeAbbrevOp::DecodeChar6(Res.get());
890b57cec5SDimitry Andric     else
900b57cec5SDimitry Andric       return Res.takeError();
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric   llvm_unreachable("invalid abbreviation encoding");
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric /// skipRecord - Read the current record and discard it.
960b57cec5SDimitry Andric Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
970b57cec5SDimitry Andric   // Skip unabbreviated records by reading past their entries.
980b57cec5SDimitry Andric   if (AbbrevID == bitc::UNABBREV_RECORD) {
990b57cec5SDimitry Andric     Expected<uint32_t> MaybeCode = ReadVBR(6);
1000b57cec5SDimitry Andric     if (!MaybeCode)
1010b57cec5SDimitry Andric       return MaybeCode.takeError();
1020b57cec5SDimitry Andric     unsigned Code = MaybeCode.get();
1030b57cec5SDimitry Andric     Expected<uint32_t> MaybeVBR = ReadVBR(6);
1040b57cec5SDimitry Andric     if (!MaybeVBR)
10581ad6265SDimitry Andric       return MaybeVBR.takeError();
1060b57cec5SDimitry Andric     unsigned NumElts = MaybeVBR.get();
1070b57cec5SDimitry Andric     for (unsigned i = 0; i != NumElts; ++i)
1080b57cec5SDimitry Andric       if (Expected<uint64_t> Res = ReadVBR64(6))
1090b57cec5SDimitry Andric         ; // Skip!
1100b57cec5SDimitry Andric       else
1110b57cec5SDimitry Andric         return Res.takeError();
1120b57cec5SDimitry Andric     return Code;
1130b57cec5SDimitry Andric   }
1140b57cec5SDimitry Andric 
11581ad6265SDimitry Andric   Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
11681ad6265SDimitry Andric   if (!MaybeAbbv)
11781ad6265SDimitry Andric     return MaybeAbbv.takeError();
11881ad6265SDimitry Andric 
11981ad6265SDimitry Andric   const BitCodeAbbrev *Abbv = MaybeAbbv.get();
1200b57cec5SDimitry Andric   const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
1210b57cec5SDimitry Andric   unsigned Code;
1220b57cec5SDimitry Andric   if (CodeOp.isLiteral())
1230b57cec5SDimitry Andric     Code = CodeOp.getLiteralValue();
1240b57cec5SDimitry Andric   else {
1250b57cec5SDimitry Andric     if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
1260b57cec5SDimitry Andric         CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
1270b57cec5SDimitry Andric       return llvm::createStringError(
1280b57cec5SDimitry Andric           std::errc::illegal_byte_sequence,
1290b57cec5SDimitry Andric           "Abbreviation starts with an Array or a Blob");
1300b57cec5SDimitry Andric     Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp);
1310b57cec5SDimitry Andric     if (!MaybeCode)
1320b57cec5SDimitry Andric       return MaybeCode.takeError();
1330b57cec5SDimitry Andric     Code = MaybeCode.get();
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i < e; ++i) {
1370b57cec5SDimitry Andric     const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
1380b57cec5SDimitry Andric     if (Op.isLiteral())
1390b57cec5SDimitry Andric       continue;
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric     if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
1420b57cec5SDimitry Andric         Op.getEncoding() != BitCodeAbbrevOp::Blob) {
143480093f4SDimitry Andric       if (Expected<uint64_t> MaybeField = readAbbreviatedField(*this, Op))
1440b57cec5SDimitry Andric         continue;
145480093f4SDimitry Andric       else
146480093f4SDimitry Andric         return MaybeField.takeError();
1470b57cec5SDimitry Andric     }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric     if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
1500b57cec5SDimitry Andric       // Array case.  Read the number of elements as a vbr6.
1510b57cec5SDimitry Andric       Expected<uint32_t> MaybeNum = ReadVBR(6);
1520b57cec5SDimitry Andric       if (!MaybeNum)
1530b57cec5SDimitry Andric         return MaybeNum.takeError();
1540b57cec5SDimitry Andric       unsigned NumElts = MaybeNum.get();
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric       // Get the element encoding.
1570b57cec5SDimitry Andric       assert(i+2 == e && "array op not second to last?");
1580b57cec5SDimitry Andric       const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric       // Read all the elements.
1610b57cec5SDimitry Andric       // Decode the value as we are commanded.
1620b57cec5SDimitry Andric       switch (EltEnc.getEncoding()) {
1630b57cec5SDimitry Andric       default:
16481ad6265SDimitry Andric         return error("Array element type can't be an Array or a Blob");
1650b57cec5SDimitry Andric       case BitCodeAbbrevOp::Fixed:
1660b57cec5SDimitry Andric         assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
167e8d8bef9SDimitry Andric         if (Error Err =
168e8d8bef9SDimitry Andric                 JumpToBit(GetCurrentBitNo() + static_cast<uint64_t>(NumElts) *
169e8d8bef9SDimitry Andric                                                   EltEnc.getEncodingData()))
170*0fca6ea1SDimitry Andric           return Err;
1710b57cec5SDimitry Andric         break;
1720b57cec5SDimitry Andric       case BitCodeAbbrevOp::VBR:
1730b57cec5SDimitry Andric         assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
1740b57cec5SDimitry Andric         for (; NumElts; --NumElts)
1750b57cec5SDimitry Andric           if (Expected<uint64_t> Res =
1760b57cec5SDimitry Andric                   ReadVBR64((unsigned)EltEnc.getEncodingData()))
1770b57cec5SDimitry Andric             ; // Skip!
1780b57cec5SDimitry Andric           else
1790b57cec5SDimitry Andric             return Res.takeError();
1800b57cec5SDimitry Andric         break;
1810b57cec5SDimitry Andric       case BitCodeAbbrevOp::Char6:
1820b57cec5SDimitry Andric         if (Error Err = JumpToBit(GetCurrentBitNo() + NumElts * 6))
183*0fca6ea1SDimitry Andric           return Err;
1840b57cec5SDimitry Andric         break;
1850b57cec5SDimitry Andric       }
1860b57cec5SDimitry Andric       continue;
1870b57cec5SDimitry Andric     }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric     assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
1900b57cec5SDimitry Andric     // Blob case.  Read the number of bytes as a vbr6.
1910b57cec5SDimitry Andric     Expected<uint32_t> MaybeNum = ReadVBR(6);
1920b57cec5SDimitry Andric     if (!MaybeNum)
1930b57cec5SDimitry Andric       return MaybeNum.takeError();
1940b57cec5SDimitry Andric     unsigned NumElts = MaybeNum.get();
1950b57cec5SDimitry Andric     SkipToFourByteBoundary();  // 32-bit alignment
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric     // Figure out where the end of this blob will be including tail padding.
198e8d8bef9SDimitry Andric     const size_t NewEnd = GetCurrentBitNo() + alignTo(NumElts, 4) * 8;
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric     // If this would read off the end of the bitcode file, just set the
2010b57cec5SDimitry Andric     // record to empty and return.
2020b57cec5SDimitry Andric     if (!canSkipToPos(NewEnd/8)) {
2030b57cec5SDimitry Andric       skipToEnd();
2040b57cec5SDimitry Andric       break;
2050b57cec5SDimitry Andric     }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric     // Skip over the blob.
2080b57cec5SDimitry Andric     if (Error Err = JumpToBit(NewEnd))
209*0fca6ea1SDimitry Andric       return Err;
2100b57cec5SDimitry Andric   }
2110b57cec5SDimitry Andric   return Code;
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
2150b57cec5SDimitry Andric                                                SmallVectorImpl<uint64_t> &Vals,
2160b57cec5SDimitry Andric                                                StringRef *Blob) {
2170b57cec5SDimitry Andric   if (AbbrevID == bitc::UNABBREV_RECORD) {
2180b57cec5SDimitry Andric     Expected<uint32_t> MaybeCode = ReadVBR(6);
2190b57cec5SDimitry Andric     if (!MaybeCode)
2200b57cec5SDimitry Andric       return MaybeCode.takeError();
2210b57cec5SDimitry Andric     uint32_t Code = MaybeCode.get();
2220b57cec5SDimitry Andric     Expected<uint32_t> MaybeNumElts = ReadVBR(6);
2230b57cec5SDimitry Andric     if (!MaybeNumElts)
22481ad6265SDimitry Andric       return error(
22581ad6265SDimitry Andric           ("Failed to read size: " + toString(MaybeNumElts.takeError()))
22681ad6265SDimitry Andric               .c_str());
2270b57cec5SDimitry Andric     uint32_t NumElts = MaybeNumElts.get();
22881ad6265SDimitry Andric     if (!isSizePlausible(NumElts))
22981ad6265SDimitry Andric       return error("Size is not plausible");
2305ffd83dbSDimitry Andric     Vals.reserve(Vals.size() + NumElts);
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric     for (unsigned i = 0; i != NumElts; ++i)
2330b57cec5SDimitry Andric       if (Expected<uint64_t> MaybeVal = ReadVBR64(6))
2340b57cec5SDimitry Andric         Vals.push_back(MaybeVal.get());
2350b57cec5SDimitry Andric       else
2360b57cec5SDimitry Andric         return MaybeVal.takeError();
2370b57cec5SDimitry Andric     return Code;
2380b57cec5SDimitry Andric   }
2390b57cec5SDimitry Andric 
24081ad6265SDimitry Andric   Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
24181ad6265SDimitry Andric   if (!MaybeAbbv)
24281ad6265SDimitry Andric     return MaybeAbbv.takeError();
24381ad6265SDimitry Andric   const BitCodeAbbrev *Abbv = MaybeAbbv.get();
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   // Read the record code first.
2460b57cec5SDimitry Andric   assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
2470b57cec5SDimitry Andric   const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
2480b57cec5SDimitry Andric   unsigned Code;
2490b57cec5SDimitry Andric   if (CodeOp.isLiteral())
2500b57cec5SDimitry Andric     Code = CodeOp.getLiteralValue();
2510b57cec5SDimitry Andric   else {
2520b57cec5SDimitry Andric     if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
2530b57cec5SDimitry Andric         CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
25481ad6265SDimitry Andric       return error("Abbreviation starts with an Array or a Blob");
2550b57cec5SDimitry Andric     if (Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp))
2560b57cec5SDimitry Andric       Code = MaybeCode.get();
2570b57cec5SDimitry Andric     else
2580b57cec5SDimitry Andric       return MaybeCode.takeError();
2590b57cec5SDimitry Andric   }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
2620b57cec5SDimitry Andric     const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
2630b57cec5SDimitry Andric     if (Op.isLiteral()) {
2640b57cec5SDimitry Andric       Vals.push_back(Op.getLiteralValue());
2650b57cec5SDimitry Andric       continue;
2660b57cec5SDimitry Andric     }
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric     if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
2690b57cec5SDimitry Andric         Op.getEncoding() != BitCodeAbbrevOp::Blob) {
2700b57cec5SDimitry Andric       if (Expected<uint64_t> MaybeVal = readAbbreviatedField(*this, Op))
2710b57cec5SDimitry Andric         Vals.push_back(MaybeVal.get());
2720b57cec5SDimitry Andric       else
2730b57cec5SDimitry Andric         return MaybeVal.takeError();
2740b57cec5SDimitry Andric       continue;
2750b57cec5SDimitry Andric     }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric     if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
2780b57cec5SDimitry Andric       // Array case.  Read the number of elements as a vbr6.
2790b57cec5SDimitry Andric       Expected<uint32_t> MaybeNumElts = ReadVBR(6);
2800b57cec5SDimitry Andric       if (!MaybeNumElts)
28181ad6265SDimitry Andric         return error(
28281ad6265SDimitry Andric             ("Failed to read size: " + toString(MaybeNumElts.takeError()))
28381ad6265SDimitry Andric                 .c_str());
2840b57cec5SDimitry Andric       uint32_t NumElts = MaybeNumElts.get();
28581ad6265SDimitry Andric       if (!isSizePlausible(NumElts))
28681ad6265SDimitry Andric         return error("Size is not plausible");
2875ffd83dbSDimitry Andric       Vals.reserve(Vals.size() + NumElts);
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric       // Get the element encoding.
2900b57cec5SDimitry Andric       if (i + 2 != e)
29181ad6265SDimitry Andric         return error("Array op not second to last");
2920b57cec5SDimitry Andric       const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
2930b57cec5SDimitry Andric       if (!EltEnc.isEncoding())
29481ad6265SDimitry Andric         return error(
2950b57cec5SDimitry Andric             "Array element type has to be an encoding of a type");
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric       // Read all the elements.
2980b57cec5SDimitry Andric       switch (EltEnc.getEncoding()) {
2990b57cec5SDimitry Andric       default:
30081ad6265SDimitry Andric         return error("Array element type can't be an Array or a Blob");
3010b57cec5SDimitry Andric       case BitCodeAbbrevOp::Fixed:
3020b57cec5SDimitry Andric         for (; NumElts; --NumElts)
3030b57cec5SDimitry Andric           if (Expected<SimpleBitstreamCursor::word_t> MaybeVal =
3040b57cec5SDimitry Andric                   Read((unsigned)EltEnc.getEncodingData()))
3050b57cec5SDimitry Andric             Vals.push_back(MaybeVal.get());
3060b57cec5SDimitry Andric           else
3070b57cec5SDimitry Andric             return MaybeVal.takeError();
3080b57cec5SDimitry Andric         break;
3090b57cec5SDimitry Andric       case BitCodeAbbrevOp::VBR:
3100b57cec5SDimitry Andric         for (; NumElts; --NumElts)
3110b57cec5SDimitry Andric           if (Expected<uint64_t> MaybeVal =
3120b57cec5SDimitry Andric                   ReadVBR64((unsigned)EltEnc.getEncodingData()))
3130b57cec5SDimitry Andric             Vals.push_back(MaybeVal.get());
3140b57cec5SDimitry Andric           else
3150b57cec5SDimitry Andric             return MaybeVal.takeError();
3160b57cec5SDimitry Andric         break;
3170b57cec5SDimitry Andric       case BitCodeAbbrevOp::Char6:
3180b57cec5SDimitry Andric         for (; NumElts; --NumElts)
3190b57cec5SDimitry Andric           if (Expected<SimpleBitstreamCursor::word_t> MaybeVal = Read(6))
3200b57cec5SDimitry Andric             Vals.push_back(BitCodeAbbrevOp::DecodeChar6(MaybeVal.get()));
3210b57cec5SDimitry Andric           else
3220b57cec5SDimitry Andric             return MaybeVal.takeError();
3230b57cec5SDimitry Andric       }
3240b57cec5SDimitry Andric       continue;
3250b57cec5SDimitry Andric     }
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric     assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
3280b57cec5SDimitry Andric     // Blob case.  Read the number of bytes as a vbr6.
3290b57cec5SDimitry Andric     Expected<uint32_t> MaybeNumElts = ReadVBR(6);
3300b57cec5SDimitry Andric     if (!MaybeNumElts)
3310b57cec5SDimitry Andric       return MaybeNumElts.takeError();
3320b57cec5SDimitry Andric     uint32_t NumElts = MaybeNumElts.get();
3330b57cec5SDimitry Andric     SkipToFourByteBoundary();  // 32-bit alignment
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric     // Figure out where the end of this blob will be including tail padding.
3360b57cec5SDimitry Andric     size_t CurBitPos = GetCurrentBitNo();
337e8d8bef9SDimitry Andric     const size_t NewEnd = CurBitPos + alignTo(NumElts, 4) * 8;
3380b57cec5SDimitry Andric 
33981ad6265SDimitry Andric     // Make sure the bitstream is large enough to contain the blob.
34081ad6265SDimitry Andric     if (!canSkipToPos(NewEnd/8))
34181ad6265SDimitry Andric       return error("Blob ends too soon");
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric     // Otherwise, inform the streamer that we need these bytes in memory.  Skip
3440b57cec5SDimitry Andric     // over tail padding first, in case jumping to NewEnd invalidates the Blob
3450b57cec5SDimitry Andric     // pointer.
3460b57cec5SDimitry Andric     if (Error Err = JumpToBit(NewEnd))
347*0fca6ea1SDimitry Andric       return Err;
3480b57cec5SDimitry Andric     const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts);
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric     // If we can return a reference to the data, do so to avoid copying it.
3510b57cec5SDimitry Andric     if (Blob) {
3520b57cec5SDimitry Andric       *Blob = StringRef(Ptr, NumElts);
3530b57cec5SDimitry Andric     } else {
3540b57cec5SDimitry Andric       // Otherwise, unpack into Vals with zero extension.
3555ffd83dbSDimitry Andric       auto *UPtr = reinterpret_cast<const unsigned char *>(Ptr);
3565ffd83dbSDimitry Andric       Vals.append(UPtr, UPtr + NumElts);
3570b57cec5SDimitry Andric     }
3580b57cec5SDimitry Andric   }
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric   return Code;
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric Error BitstreamCursor::ReadAbbrevRecord() {
3640b57cec5SDimitry Andric   auto Abbv = std::make_shared<BitCodeAbbrev>();
3650b57cec5SDimitry Andric   Expected<uint32_t> MaybeNumOpInfo = ReadVBR(5);
3660b57cec5SDimitry Andric   if (!MaybeNumOpInfo)
3670b57cec5SDimitry Andric     return MaybeNumOpInfo.takeError();
3680b57cec5SDimitry Andric   unsigned NumOpInfo = MaybeNumOpInfo.get();
3690b57cec5SDimitry Andric   for (unsigned i = 0; i != NumOpInfo; ++i) {
3700b57cec5SDimitry Andric     Expected<word_t> MaybeIsLiteral = Read(1);
3710b57cec5SDimitry Andric     if (!MaybeIsLiteral)
3720b57cec5SDimitry Andric       return MaybeIsLiteral.takeError();
3730b57cec5SDimitry Andric     bool IsLiteral = MaybeIsLiteral.get();
3740b57cec5SDimitry Andric     if (IsLiteral) {
3750b57cec5SDimitry Andric       Expected<uint64_t> MaybeOp = ReadVBR64(8);
3760b57cec5SDimitry Andric       if (!MaybeOp)
3770b57cec5SDimitry Andric         return MaybeOp.takeError();
3780b57cec5SDimitry Andric       Abbv->Add(BitCodeAbbrevOp(MaybeOp.get()));
3790b57cec5SDimitry Andric       continue;
3800b57cec5SDimitry Andric     }
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric     Expected<word_t> MaybeEncoding = Read(3);
3830b57cec5SDimitry Andric     if (!MaybeEncoding)
3840b57cec5SDimitry Andric       return MaybeEncoding.takeError();
38581ad6265SDimitry Andric     if (!BitCodeAbbrevOp::isValidEncoding(MaybeEncoding.get()))
38681ad6265SDimitry Andric       return error("Invalid encoding");
38781ad6265SDimitry Andric 
3880b57cec5SDimitry Andric     BitCodeAbbrevOp::Encoding E =
3890b57cec5SDimitry Andric         (BitCodeAbbrevOp::Encoding)MaybeEncoding.get();
3900b57cec5SDimitry Andric     if (BitCodeAbbrevOp::hasEncodingData(E)) {
3910b57cec5SDimitry Andric       Expected<uint64_t> MaybeData = ReadVBR64(5);
3920b57cec5SDimitry Andric       if (!MaybeData)
3930b57cec5SDimitry Andric         return MaybeData.takeError();
3940b57cec5SDimitry Andric       uint64_t Data = MaybeData.get();
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric       // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
3970b57cec5SDimitry Andric       // and vbr(0) as a literal zero.  This is decoded the same way, and avoids
3980b57cec5SDimitry Andric       // a slow path in Read() to have to handle reading zero bits.
3990b57cec5SDimitry Andric       if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
4000b57cec5SDimitry Andric           Data == 0) {
4010b57cec5SDimitry Andric         Abbv->Add(BitCodeAbbrevOp(0));
4020b57cec5SDimitry Andric         continue;
4030b57cec5SDimitry Andric       }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric       if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
4060b57cec5SDimitry Andric           Data > MaxChunkSize)
40781ad6265SDimitry Andric         return error("Fixed or VBR abbrev record with size > MaxChunkData");
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric       Abbv->Add(BitCodeAbbrevOp(E, Data));
4100b57cec5SDimitry Andric     } else
4110b57cec5SDimitry Andric       Abbv->Add(BitCodeAbbrevOp(E));
4120b57cec5SDimitry Andric   }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   if (Abbv->getNumOperandInfos() == 0)
41581ad6265SDimitry Andric     return error("Abbrev record with no operands");
4160b57cec5SDimitry Andric   CurAbbrevs.push_back(std::move(Abbv));
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   return Error::success();
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
421bdd1243dSDimitry Andric Expected<std::optional<BitstreamBlockInfo>>
4220b57cec5SDimitry Andric BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) {
4230b57cec5SDimitry Andric   if (llvm::Error Err = EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID))
424*0fca6ea1SDimitry Andric     return Err;
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   BitstreamBlockInfo NewBlockInfo;
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric   SmallVector<uint64_t, 64> Record;
4290b57cec5SDimitry Andric   BitstreamBlockInfo::BlockInfo *CurBlockInfo = nullptr;
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   // Read all the records for this module.
4320b57cec5SDimitry Andric   while (true) {
4330b57cec5SDimitry Andric     Expected<BitstreamEntry> MaybeEntry =
4340b57cec5SDimitry Andric         advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
4350b57cec5SDimitry Andric     if (!MaybeEntry)
4360b57cec5SDimitry Andric       return MaybeEntry.takeError();
4370b57cec5SDimitry Andric     BitstreamEntry Entry = MaybeEntry.get();
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric     switch (Entry.Kind) {
4400b57cec5SDimitry Andric     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
4410b57cec5SDimitry Andric     case llvm::BitstreamEntry::Error:
442bdd1243dSDimitry Andric       return std::nullopt;
4430b57cec5SDimitry Andric     case llvm::BitstreamEntry::EndBlock:
4440b57cec5SDimitry Andric       return std::move(NewBlockInfo);
4450b57cec5SDimitry Andric     case llvm::BitstreamEntry::Record:
4460b57cec5SDimitry Andric       // The interesting case.
4470b57cec5SDimitry Andric       break;
4480b57cec5SDimitry Andric     }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric     // Read abbrev records, associate them with CurBID.
4510b57cec5SDimitry Andric     if (Entry.ID == bitc::DEFINE_ABBREV) {
452bdd1243dSDimitry Andric       if (!CurBlockInfo)
453bdd1243dSDimitry Andric         return std::nullopt;
4540b57cec5SDimitry Andric       if (Error Err = ReadAbbrevRecord())
455*0fca6ea1SDimitry Andric         return Err;
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric       // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
4580b57cec5SDimitry Andric       // appropriate BlockInfo.
4590b57cec5SDimitry Andric       CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
4600b57cec5SDimitry Andric       CurAbbrevs.pop_back();
4610b57cec5SDimitry Andric       continue;
4620b57cec5SDimitry Andric     }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric     // Read a record.
4650b57cec5SDimitry Andric     Record.clear();
4660b57cec5SDimitry Andric     Expected<unsigned> MaybeBlockInfo = readRecord(Entry.ID, Record);
4670b57cec5SDimitry Andric     if (!MaybeBlockInfo)
4680b57cec5SDimitry Andric       return MaybeBlockInfo.takeError();
4690b57cec5SDimitry Andric     switch (MaybeBlockInfo.get()) {
4700b57cec5SDimitry Andric     default:
4710b57cec5SDimitry Andric       break; // Default behavior, ignore unknown content.
4720b57cec5SDimitry Andric     case bitc::BLOCKINFO_CODE_SETBID:
4730b57cec5SDimitry Andric       if (Record.size() < 1)
474bdd1243dSDimitry Andric         return std::nullopt;
4750b57cec5SDimitry Andric       CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]);
4760b57cec5SDimitry Andric       break;
4770b57cec5SDimitry Andric     case bitc::BLOCKINFO_CODE_BLOCKNAME: {
4780b57cec5SDimitry Andric       if (!CurBlockInfo)
479bdd1243dSDimitry Andric         return std::nullopt;
4800b57cec5SDimitry Andric       if (!ReadBlockInfoNames)
4810b57cec5SDimitry Andric         break; // Ignore name.
4825ffd83dbSDimitry Andric       CurBlockInfo->Name = std::string(Record.begin(), Record.end());
4830b57cec5SDimitry Andric       break;
4840b57cec5SDimitry Andric     }
4850b57cec5SDimitry Andric       case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
486bdd1243dSDimitry Andric       if (!CurBlockInfo)
487bdd1243dSDimitry Andric         return std::nullopt;
4880b57cec5SDimitry Andric       if (!ReadBlockInfoNames)
4890b57cec5SDimitry Andric         break; // Ignore name.
4905ffd83dbSDimitry Andric       CurBlockInfo->RecordNames.emplace_back(
4915ffd83dbSDimitry Andric           (unsigned)Record[0], std::string(Record.begin() + 1, Record.end()));
4920b57cec5SDimitry Andric       break;
4930b57cec5SDimitry Andric       }
4940b57cec5SDimitry Andric       }
4950b57cec5SDimitry Andric   }
4960b57cec5SDimitry Andric }
497