109467b48Spatrick //===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This header defines the BitstreamReader class. This class can be used to 1009467b48Spatrick // read an arbitrary bitstream, regardless of its contents. 1109467b48Spatrick // 1209467b48Spatrick //===----------------------------------------------------------------------===// 1309467b48Spatrick 1409467b48Spatrick #ifndef LLVM_BITSTREAM_BITSTREAMREADER_H 1509467b48Spatrick #define LLVM_BITSTREAM_BITSTREAMREADER_H 1609467b48Spatrick 1709467b48Spatrick #include "llvm/ADT/ArrayRef.h" 1809467b48Spatrick #include "llvm/ADT/SmallVector.h" 1909467b48Spatrick #include "llvm/Bitstream/BitCodes.h" 2009467b48Spatrick #include "llvm/Support/Endian.h" 21097a140dSpatrick #include "llvm/Support/Error.h" 22*d415bd75Srobert #include "llvm/Support/MemoryBufferRef.h" 2309467b48Spatrick #include <algorithm> 2409467b48Spatrick #include <cassert> 2509467b48Spatrick #include <climits> 2609467b48Spatrick #include <cstddef> 2709467b48Spatrick #include <cstdint> 2809467b48Spatrick #include <memory> 29*d415bd75Srobert #include <optional> 3009467b48Spatrick #include <string> 3109467b48Spatrick #include <utility> 3209467b48Spatrick #include <vector> 3309467b48Spatrick 3409467b48Spatrick namespace llvm { 3509467b48Spatrick 3609467b48Spatrick /// This class maintains the abbreviations read from a block info block. 3709467b48Spatrick class BitstreamBlockInfo { 3809467b48Spatrick public: 3909467b48Spatrick /// This contains information emitted to BLOCKINFO_BLOCK blocks. These 4009467b48Spatrick /// describe abbreviations that all blocks of the specified ID inherit. 4109467b48Spatrick struct BlockInfo { 4209467b48Spatrick unsigned BlockID = 0; 4309467b48Spatrick std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs; 4409467b48Spatrick std::string Name; 4509467b48Spatrick std::vector<std::pair<unsigned, std::string>> RecordNames; 4609467b48Spatrick }; 4709467b48Spatrick 4809467b48Spatrick private: 4909467b48Spatrick std::vector<BlockInfo> BlockInfoRecords; 5009467b48Spatrick 5109467b48Spatrick public: 5209467b48Spatrick /// If there is block info for the specified ID, return it, otherwise return 5309467b48Spatrick /// null. getBlockInfo(unsigned BlockID)5409467b48Spatrick const BlockInfo *getBlockInfo(unsigned BlockID) const { 5509467b48Spatrick // Common case, the most recent entry matches BlockID. 5609467b48Spatrick if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) 5709467b48Spatrick return &BlockInfoRecords.back(); 5809467b48Spatrick 59*d415bd75Srobert for (const BlockInfo &BI : BlockInfoRecords) 60*d415bd75Srobert if (BI.BlockID == BlockID) 61*d415bd75Srobert return &BI; 6209467b48Spatrick return nullptr; 6309467b48Spatrick } 6409467b48Spatrick getOrCreateBlockInfo(unsigned BlockID)6509467b48Spatrick BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { 6609467b48Spatrick if (const BlockInfo *BI = getBlockInfo(BlockID)) 6709467b48Spatrick return *const_cast<BlockInfo*>(BI); 6809467b48Spatrick 6909467b48Spatrick // Otherwise, add a new record. 7009467b48Spatrick BlockInfoRecords.emplace_back(); 7109467b48Spatrick BlockInfoRecords.back().BlockID = BlockID; 7209467b48Spatrick return BlockInfoRecords.back(); 7309467b48Spatrick } 7409467b48Spatrick }; 7509467b48Spatrick 7609467b48Spatrick /// This represents a position within a bitstream. There may be multiple 7709467b48Spatrick /// independent cursors reading within one bitstream, each maintaining their 7809467b48Spatrick /// own local state. 7909467b48Spatrick class SimpleBitstreamCursor { 8009467b48Spatrick ArrayRef<uint8_t> BitcodeBytes; 8109467b48Spatrick size_t NextChar = 0; 8209467b48Spatrick 8309467b48Spatrick public: 8409467b48Spatrick /// This is the current data we have pulled from the stream but have not 8509467b48Spatrick /// returned to the client. This is specifically and intentionally defined to 8609467b48Spatrick /// follow the word size of the host machine for efficiency. We use word_t in 8709467b48Spatrick /// places that are aware of this to make it perfectly explicit what is going 8809467b48Spatrick /// on. 8909467b48Spatrick using word_t = size_t; 9009467b48Spatrick 9109467b48Spatrick private: 9209467b48Spatrick word_t CurWord = 0; 9309467b48Spatrick 9409467b48Spatrick /// This is the number of bits in CurWord that are valid. This is always from 9509467b48Spatrick /// [0...bits_of(size_t)-1] inclusive. 9609467b48Spatrick unsigned BitsInCurWord = 0; 9709467b48Spatrick 9809467b48Spatrick public: 9909467b48Spatrick SimpleBitstreamCursor() = default; SimpleBitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)10009467b48Spatrick explicit SimpleBitstreamCursor(ArrayRef<uint8_t> BitcodeBytes) 10109467b48Spatrick : BitcodeBytes(BitcodeBytes) {} SimpleBitstreamCursor(StringRef BitcodeBytes)10209467b48Spatrick explicit SimpleBitstreamCursor(StringRef BitcodeBytes) 10309467b48Spatrick : BitcodeBytes(arrayRefFromStringRef(BitcodeBytes)) {} SimpleBitstreamCursor(MemoryBufferRef BitcodeBytes)10409467b48Spatrick explicit SimpleBitstreamCursor(MemoryBufferRef BitcodeBytes) 10509467b48Spatrick : SimpleBitstreamCursor(BitcodeBytes.getBuffer()) {} 10609467b48Spatrick canSkipToPos(size_t pos)10709467b48Spatrick bool canSkipToPos(size_t pos) const { 10809467b48Spatrick // pos can be skipped to if it is a valid address or one byte past the end. 10909467b48Spatrick return pos <= BitcodeBytes.size(); 11009467b48Spatrick } 11109467b48Spatrick AtEndOfStream()11209467b48Spatrick bool AtEndOfStream() { 11309467b48Spatrick return BitsInCurWord == 0 && BitcodeBytes.size() <= NextChar; 11409467b48Spatrick } 11509467b48Spatrick 11609467b48Spatrick /// Return the bit # of the bit we are reading. GetCurrentBitNo()11709467b48Spatrick uint64_t GetCurrentBitNo() const { 11809467b48Spatrick return NextChar*CHAR_BIT - BitsInCurWord; 11909467b48Spatrick } 12009467b48Spatrick 12109467b48Spatrick // Return the byte # of the current bit. getCurrentByteNo()12209467b48Spatrick uint64_t getCurrentByteNo() const { return GetCurrentBitNo() / 8; } 12309467b48Spatrick getBitcodeBytes()12409467b48Spatrick ArrayRef<uint8_t> getBitcodeBytes() const { return BitcodeBytes; } 12509467b48Spatrick 12609467b48Spatrick /// Reset the stream to the specified bit number. JumpToBit(uint64_t BitNo)12709467b48Spatrick Error JumpToBit(uint64_t BitNo) { 12809467b48Spatrick size_t ByteNo = size_t(BitNo/8) & ~(sizeof(word_t)-1); 12909467b48Spatrick unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); 13009467b48Spatrick assert(canSkipToPos(ByteNo) && "Invalid location"); 13109467b48Spatrick 13209467b48Spatrick // Move the cursor to the right word. 13309467b48Spatrick NextChar = ByteNo; 13409467b48Spatrick BitsInCurWord = 0; 13509467b48Spatrick 13609467b48Spatrick // Skip over any bits that are already consumed. 13709467b48Spatrick if (WordBitNo) { 13809467b48Spatrick if (Expected<word_t> Res = Read(WordBitNo)) 13909467b48Spatrick return Error::success(); 14009467b48Spatrick else 14109467b48Spatrick return Res.takeError(); 14209467b48Spatrick } 14309467b48Spatrick 14409467b48Spatrick return Error::success(); 14509467b48Spatrick } 14609467b48Spatrick 14709467b48Spatrick /// Get a pointer into the bitstream at the specified byte offset. getPointerToByte(uint64_t ByteNo,uint64_t NumBytes)14809467b48Spatrick const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) { 14909467b48Spatrick return BitcodeBytes.data() + ByteNo; 15009467b48Spatrick } 15109467b48Spatrick 15209467b48Spatrick /// Get a pointer into the bitstream at the specified bit offset. 15309467b48Spatrick /// 15409467b48Spatrick /// The bit offset must be on a byte boundary. getPointerToBit(uint64_t BitNo,uint64_t NumBytes)15509467b48Spatrick const uint8_t *getPointerToBit(uint64_t BitNo, uint64_t NumBytes) { 15609467b48Spatrick assert(!(BitNo % 8) && "Expected bit on byte boundary"); 15709467b48Spatrick return getPointerToByte(BitNo / 8, NumBytes); 15809467b48Spatrick } 15909467b48Spatrick fillCurWord()16009467b48Spatrick Error fillCurWord() { 16109467b48Spatrick if (NextChar >= BitcodeBytes.size()) 16209467b48Spatrick return createStringError(std::errc::io_error, 16309467b48Spatrick "Unexpected end of file reading %u of %u bytes", 16409467b48Spatrick NextChar, BitcodeBytes.size()); 16509467b48Spatrick 16609467b48Spatrick // Read the next word from the stream. 16709467b48Spatrick const uint8_t *NextCharPtr = BitcodeBytes.data() + NextChar; 16809467b48Spatrick unsigned BytesRead; 16909467b48Spatrick if (BitcodeBytes.size() >= NextChar + sizeof(word_t)) { 17009467b48Spatrick BytesRead = sizeof(word_t); 17109467b48Spatrick CurWord = 17209467b48Spatrick support::endian::read<word_t, support::little, support::unaligned>( 17309467b48Spatrick NextCharPtr); 17409467b48Spatrick } else { 17509467b48Spatrick // Short read. 17609467b48Spatrick BytesRead = BitcodeBytes.size() - NextChar; 17709467b48Spatrick CurWord = 0; 17809467b48Spatrick for (unsigned B = 0; B != BytesRead; ++B) 17909467b48Spatrick CurWord |= uint64_t(NextCharPtr[B]) << (B * 8); 18009467b48Spatrick } 18109467b48Spatrick NextChar += BytesRead; 18209467b48Spatrick BitsInCurWord = BytesRead * 8; 18309467b48Spatrick return Error::success(); 18409467b48Spatrick } 18509467b48Spatrick Read(unsigned NumBits)18609467b48Spatrick Expected<word_t> Read(unsigned NumBits) { 187*d415bd75Srobert static const unsigned BitsInWord = sizeof(word_t) * 8; 18809467b48Spatrick 18909467b48Spatrick assert(NumBits && NumBits <= BitsInWord && 19009467b48Spatrick "Cannot return zero or more than BitsInWord bits!"); 19109467b48Spatrick 19209467b48Spatrick static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f; 19309467b48Spatrick 19409467b48Spatrick // If the field is fully contained by CurWord, return it quickly. 19509467b48Spatrick if (BitsInCurWord >= NumBits) { 19609467b48Spatrick word_t R = CurWord & (~word_t(0) >> (BitsInWord - NumBits)); 19709467b48Spatrick 19809467b48Spatrick // Use a mask to avoid undefined behavior. 19909467b48Spatrick CurWord >>= (NumBits & Mask); 20009467b48Spatrick 20109467b48Spatrick BitsInCurWord -= NumBits; 20209467b48Spatrick return R; 20309467b48Spatrick } 20409467b48Spatrick 20509467b48Spatrick word_t R = BitsInCurWord ? CurWord : 0; 20609467b48Spatrick unsigned BitsLeft = NumBits - BitsInCurWord; 20709467b48Spatrick 20809467b48Spatrick if (Error fillResult = fillCurWord()) 20909467b48Spatrick return std::move(fillResult); 21009467b48Spatrick 21109467b48Spatrick // If we run out of data, abort. 21209467b48Spatrick if (BitsLeft > BitsInCurWord) 21309467b48Spatrick return createStringError(std::errc::io_error, 21409467b48Spatrick "Unexpected end of file reading %u of %u bits", 21509467b48Spatrick BitsInCurWord, BitsLeft); 21609467b48Spatrick 21709467b48Spatrick word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft)); 21809467b48Spatrick 21909467b48Spatrick // Use a mask to avoid undefined behavior. 22009467b48Spatrick CurWord >>= (BitsLeft & Mask); 22109467b48Spatrick 22209467b48Spatrick BitsInCurWord -= BitsLeft; 22309467b48Spatrick 22409467b48Spatrick R |= R2 << (NumBits - BitsLeft); 22509467b48Spatrick 22609467b48Spatrick return R; 22709467b48Spatrick } 22809467b48Spatrick ReadVBR(const unsigned NumBits)229*d415bd75Srobert Expected<uint32_t> ReadVBR(const unsigned NumBits) { 23009467b48Spatrick Expected<unsigned> MaybeRead = Read(NumBits); 23109467b48Spatrick if (!MaybeRead) 23209467b48Spatrick return MaybeRead; 23309467b48Spatrick uint32_t Piece = MaybeRead.get(); 23409467b48Spatrick 235*d415bd75Srobert assert(NumBits <= 32 && NumBits >= 1 && "Invalid NumBits value"); 236*d415bd75Srobert const uint32_t MaskBitOrder = (NumBits - 1); 237*d415bd75Srobert const uint32_t Mask = 1UL << MaskBitOrder; 238*d415bd75Srobert 239*d415bd75Srobert if ((Piece & Mask) == 0) 24009467b48Spatrick return Piece; 24109467b48Spatrick 24209467b48Spatrick uint32_t Result = 0; 24309467b48Spatrick unsigned NextBit = 0; 24409467b48Spatrick while (true) { 245*d415bd75Srobert Result |= (Piece & (Mask - 1)) << NextBit; 24609467b48Spatrick 247*d415bd75Srobert if ((Piece & Mask) == 0) 24809467b48Spatrick return Result; 24909467b48Spatrick 25009467b48Spatrick NextBit += NumBits-1; 251*d415bd75Srobert if (NextBit >= 32) 252*d415bd75Srobert return createStringError(std::errc::illegal_byte_sequence, 253*d415bd75Srobert "Unterminated VBR"); 254*d415bd75Srobert 25509467b48Spatrick MaybeRead = Read(NumBits); 25609467b48Spatrick if (!MaybeRead) 25709467b48Spatrick return MaybeRead; 25809467b48Spatrick Piece = MaybeRead.get(); 25909467b48Spatrick } 26009467b48Spatrick } 26109467b48Spatrick 26209467b48Spatrick // Read a VBR that may have a value up to 64-bits in size. The chunk size of 26309467b48Spatrick // the VBR must still be <= 32 bits though. ReadVBR64(const unsigned NumBits)264*d415bd75Srobert Expected<uint64_t> ReadVBR64(const unsigned NumBits) { 26509467b48Spatrick Expected<uint64_t> MaybeRead = Read(NumBits); 26609467b48Spatrick if (!MaybeRead) 26709467b48Spatrick return MaybeRead; 26809467b48Spatrick uint32_t Piece = MaybeRead.get(); 269*d415bd75Srobert assert(NumBits <= 32 && NumBits >= 1 && "Invalid NumBits value"); 270*d415bd75Srobert const uint32_t MaskBitOrder = (NumBits - 1); 271*d415bd75Srobert const uint32_t Mask = 1UL << MaskBitOrder; 27209467b48Spatrick 273*d415bd75Srobert if ((Piece & Mask) == 0) 27409467b48Spatrick return uint64_t(Piece); 27509467b48Spatrick 27609467b48Spatrick uint64_t Result = 0; 27709467b48Spatrick unsigned NextBit = 0; 27809467b48Spatrick while (true) { 279*d415bd75Srobert Result |= uint64_t(Piece & (Mask - 1)) << NextBit; 28009467b48Spatrick 281*d415bd75Srobert if ((Piece & Mask) == 0) 28209467b48Spatrick return Result; 28309467b48Spatrick 28409467b48Spatrick NextBit += NumBits-1; 285*d415bd75Srobert if (NextBit >= 64) 286*d415bd75Srobert return createStringError(std::errc::illegal_byte_sequence, 287*d415bd75Srobert "Unterminated VBR"); 288*d415bd75Srobert 28909467b48Spatrick MaybeRead = Read(NumBits); 29009467b48Spatrick if (!MaybeRead) 29109467b48Spatrick return MaybeRead; 29209467b48Spatrick Piece = MaybeRead.get(); 29309467b48Spatrick } 29409467b48Spatrick } 29509467b48Spatrick SkipToFourByteBoundary()29609467b48Spatrick void SkipToFourByteBoundary() { 29709467b48Spatrick // If word_t is 64-bits and if we've read less than 32 bits, just dump 29809467b48Spatrick // the bits we have up to the next 32-bit boundary. 29909467b48Spatrick if (sizeof(word_t) > 4 && 30009467b48Spatrick BitsInCurWord >= 32) { 30109467b48Spatrick CurWord >>= BitsInCurWord-32; 30209467b48Spatrick BitsInCurWord = 32; 30309467b48Spatrick return; 30409467b48Spatrick } 30509467b48Spatrick 30609467b48Spatrick BitsInCurWord = 0; 30709467b48Spatrick } 30809467b48Spatrick 30909467b48Spatrick /// Return the size of the stream in bytes. SizeInBytes()31009467b48Spatrick size_t SizeInBytes() const { return BitcodeBytes.size(); } 31109467b48Spatrick 31209467b48Spatrick /// Skip to the end of the file. skipToEnd()31309467b48Spatrick void skipToEnd() { NextChar = BitcodeBytes.size(); } 314*d415bd75Srobert 315*d415bd75Srobert /// Check whether a reservation of Size elements is plausible. isSizePlausible(size_t Size)316*d415bd75Srobert bool isSizePlausible(size_t Size) const { 317*d415bd75Srobert // Don't allow reserving more elements than the number of bits, assuming 318*d415bd75Srobert // at least one bit is needed to encode an element. 319*d415bd75Srobert return Size < BitcodeBytes.size() * 8; 320*d415bd75Srobert } 32109467b48Spatrick }; 32209467b48Spatrick 32309467b48Spatrick /// When advancing through a bitstream cursor, each advance can discover a few 32409467b48Spatrick /// different kinds of entries: 32509467b48Spatrick struct BitstreamEntry { 32609467b48Spatrick enum { 32709467b48Spatrick Error, // Malformed bitcode was found. 32809467b48Spatrick EndBlock, // We've reached the end of the current block, (or the end of the 32909467b48Spatrick // file, which is treated like a series of EndBlock records. 33009467b48Spatrick SubBlock, // This is the start of a new subblock of a specific ID. 33109467b48Spatrick Record // This is a record with a specific AbbrevID. 33209467b48Spatrick } Kind; 33309467b48Spatrick 33409467b48Spatrick unsigned ID; 33509467b48Spatrick getErrorBitstreamEntry33609467b48Spatrick static BitstreamEntry getError() { 33709467b48Spatrick BitstreamEntry E; E.Kind = Error; return E; 33809467b48Spatrick } 33909467b48Spatrick getEndBlockBitstreamEntry34009467b48Spatrick static BitstreamEntry getEndBlock() { 34109467b48Spatrick BitstreamEntry E; E.Kind = EndBlock; return E; 34209467b48Spatrick } 34309467b48Spatrick getSubBlockBitstreamEntry34409467b48Spatrick static BitstreamEntry getSubBlock(unsigned ID) { 34509467b48Spatrick BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; 34609467b48Spatrick } 34709467b48Spatrick getRecordBitstreamEntry34809467b48Spatrick static BitstreamEntry getRecord(unsigned AbbrevID) { 34909467b48Spatrick BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; 35009467b48Spatrick } 35109467b48Spatrick }; 35209467b48Spatrick 35309467b48Spatrick /// This represents a position within a bitcode file, implemented on top of a 35409467b48Spatrick /// SimpleBitstreamCursor. 35509467b48Spatrick /// 35609467b48Spatrick /// Unlike iterators, BitstreamCursors are heavy-weight objects that should not 35709467b48Spatrick /// be passed by value. 35809467b48Spatrick class BitstreamCursor : SimpleBitstreamCursor { 35909467b48Spatrick // This is the declared size of code values used for the current block, in 36009467b48Spatrick // bits. 36109467b48Spatrick unsigned CurCodeSize = 2; 36209467b48Spatrick 36309467b48Spatrick /// Abbrevs installed at in this block. 36409467b48Spatrick std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs; 36509467b48Spatrick 36609467b48Spatrick struct Block { 36709467b48Spatrick unsigned PrevCodeSize; 36809467b48Spatrick std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs; 36909467b48Spatrick BlockBlock37009467b48Spatrick explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} 37109467b48Spatrick }; 37209467b48Spatrick 37309467b48Spatrick /// This tracks the codesize of parent blocks. 37409467b48Spatrick SmallVector<Block, 8> BlockScope; 37509467b48Spatrick 37609467b48Spatrick BitstreamBlockInfo *BlockInfo = nullptr; 37709467b48Spatrick 37809467b48Spatrick public: 379*d415bd75Srobert static const size_t MaxChunkSize = 32; 38009467b48Spatrick 38109467b48Spatrick BitstreamCursor() = default; BitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)38209467b48Spatrick explicit BitstreamCursor(ArrayRef<uint8_t> BitcodeBytes) 38309467b48Spatrick : SimpleBitstreamCursor(BitcodeBytes) {} BitstreamCursor(StringRef BitcodeBytes)38409467b48Spatrick explicit BitstreamCursor(StringRef BitcodeBytes) 38509467b48Spatrick : SimpleBitstreamCursor(BitcodeBytes) {} BitstreamCursor(MemoryBufferRef BitcodeBytes)38609467b48Spatrick explicit BitstreamCursor(MemoryBufferRef BitcodeBytes) 38709467b48Spatrick : SimpleBitstreamCursor(BitcodeBytes) {} 38809467b48Spatrick 38909467b48Spatrick using SimpleBitstreamCursor::AtEndOfStream; 39009467b48Spatrick using SimpleBitstreamCursor::canSkipToPos; 39109467b48Spatrick using SimpleBitstreamCursor::fillCurWord; 39209467b48Spatrick using SimpleBitstreamCursor::getBitcodeBytes; 39309467b48Spatrick using SimpleBitstreamCursor::GetCurrentBitNo; 39409467b48Spatrick using SimpleBitstreamCursor::getCurrentByteNo; 39509467b48Spatrick using SimpleBitstreamCursor::getPointerToByte; 39609467b48Spatrick using SimpleBitstreamCursor::JumpToBit; 39709467b48Spatrick using SimpleBitstreamCursor::Read; 39809467b48Spatrick using SimpleBitstreamCursor::ReadVBR; 39909467b48Spatrick using SimpleBitstreamCursor::ReadVBR64; 40009467b48Spatrick using SimpleBitstreamCursor::SizeInBytes; 40109467b48Spatrick using SimpleBitstreamCursor::skipToEnd; 40209467b48Spatrick 40309467b48Spatrick /// Return the number of bits used to encode an abbrev #. getAbbrevIDWidth()40409467b48Spatrick unsigned getAbbrevIDWidth() const { return CurCodeSize; } 40509467b48Spatrick 40609467b48Spatrick /// Flags that modify the behavior of advance(). 40709467b48Spatrick enum { 40809467b48Spatrick /// If this flag is used, the advance() method does not automatically pop 40909467b48Spatrick /// the block scope when the end of a block is reached. 41009467b48Spatrick AF_DontPopBlockAtEnd = 1, 41109467b48Spatrick 41209467b48Spatrick /// If this flag is used, abbrev entries are returned just like normal 41309467b48Spatrick /// records. 41409467b48Spatrick AF_DontAutoprocessAbbrevs = 2 41509467b48Spatrick }; 41609467b48Spatrick 41709467b48Spatrick /// Advance the current bitstream, returning the next entry in the stream. 41809467b48Spatrick Expected<BitstreamEntry> advance(unsigned Flags = 0) { 41909467b48Spatrick while (true) { 42009467b48Spatrick if (AtEndOfStream()) 42109467b48Spatrick return BitstreamEntry::getError(); 42209467b48Spatrick 42309467b48Spatrick Expected<unsigned> MaybeCode = ReadCode(); 42409467b48Spatrick if (!MaybeCode) 42509467b48Spatrick return MaybeCode.takeError(); 42609467b48Spatrick unsigned Code = MaybeCode.get(); 42709467b48Spatrick 42809467b48Spatrick if (Code == bitc::END_BLOCK) { 42909467b48Spatrick // Pop the end of the block unless Flags tells us not to. 43009467b48Spatrick if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) 43109467b48Spatrick return BitstreamEntry::getError(); 43209467b48Spatrick return BitstreamEntry::getEndBlock(); 43309467b48Spatrick } 43409467b48Spatrick 43509467b48Spatrick if (Code == bitc::ENTER_SUBBLOCK) { 43609467b48Spatrick if (Expected<unsigned> MaybeSubBlock = ReadSubBlockID()) 43709467b48Spatrick return BitstreamEntry::getSubBlock(MaybeSubBlock.get()); 43809467b48Spatrick else 43909467b48Spatrick return MaybeSubBlock.takeError(); 44009467b48Spatrick } 44109467b48Spatrick 44209467b48Spatrick if (Code == bitc::DEFINE_ABBREV && 44309467b48Spatrick !(Flags & AF_DontAutoprocessAbbrevs)) { 44409467b48Spatrick // We read and accumulate abbrev's, the client can't do anything with 44509467b48Spatrick // them anyway. 44609467b48Spatrick if (Error Err = ReadAbbrevRecord()) 44709467b48Spatrick return std::move(Err); 44809467b48Spatrick continue; 44909467b48Spatrick } 45009467b48Spatrick 45109467b48Spatrick return BitstreamEntry::getRecord(Code); 45209467b48Spatrick } 45309467b48Spatrick } 45409467b48Spatrick 45509467b48Spatrick /// This is a convenience function for clients that don't expect any 45609467b48Spatrick /// subblocks. This just skips over them automatically. 45709467b48Spatrick Expected<BitstreamEntry> advanceSkippingSubblocks(unsigned Flags = 0) { 45809467b48Spatrick while (true) { 45909467b48Spatrick // If we found a normal entry, return it. 46009467b48Spatrick Expected<BitstreamEntry> MaybeEntry = advance(Flags); 46109467b48Spatrick if (!MaybeEntry) 46209467b48Spatrick return MaybeEntry; 46309467b48Spatrick BitstreamEntry Entry = MaybeEntry.get(); 46409467b48Spatrick 46509467b48Spatrick if (Entry.Kind != BitstreamEntry::SubBlock) 46609467b48Spatrick return Entry; 46709467b48Spatrick 46809467b48Spatrick // If we found a sub-block, just skip over it and check the next entry. 46909467b48Spatrick if (Error Err = SkipBlock()) 47009467b48Spatrick return std::move(Err); 47109467b48Spatrick } 47209467b48Spatrick } 47309467b48Spatrick ReadCode()47409467b48Spatrick Expected<unsigned> ReadCode() { return Read(CurCodeSize); } 47509467b48Spatrick 47609467b48Spatrick // Block header: 47709467b48Spatrick // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] 47809467b48Spatrick 47909467b48Spatrick /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. ReadSubBlockID()48009467b48Spatrick Expected<unsigned> ReadSubBlockID() { return ReadVBR(bitc::BlockIDWidth); } 48109467b48Spatrick 48209467b48Spatrick /// Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body 48309467b48Spatrick /// of this block. SkipBlock()48409467b48Spatrick Error SkipBlock() { 48509467b48Spatrick // Read and ignore the codelen value. 48609467b48Spatrick if (Expected<uint32_t> Res = ReadVBR(bitc::CodeLenWidth)) 48709467b48Spatrick ; // Since we are skipping this block, we don't care what code widths are 48809467b48Spatrick // used inside of it. 48909467b48Spatrick else 49009467b48Spatrick return Res.takeError(); 49109467b48Spatrick 49209467b48Spatrick SkipToFourByteBoundary(); 49309467b48Spatrick Expected<unsigned> MaybeNum = Read(bitc::BlockSizeWidth); 49409467b48Spatrick if (!MaybeNum) 49509467b48Spatrick return MaybeNum.takeError(); 49609467b48Spatrick size_t NumFourBytes = MaybeNum.get(); 49709467b48Spatrick 49809467b48Spatrick // Check that the block wasn't partially defined, and that the offset isn't 49909467b48Spatrick // bogus. 50009467b48Spatrick size_t SkipTo = GetCurrentBitNo() + NumFourBytes * 4 * 8; 50109467b48Spatrick if (AtEndOfStream()) 50209467b48Spatrick return createStringError(std::errc::illegal_byte_sequence, 50309467b48Spatrick "can't skip block: already at end of stream"); 50409467b48Spatrick if (!canSkipToPos(SkipTo / 8)) 50509467b48Spatrick return createStringError(std::errc::illegal_byte_sequence, 50609467b48Spatrick "can't skip to bit %zu from %" PRIu64, SkipTo, 50709467b48Spatrick GetCurrentBitNo()); 50809467b48Spatrick 50909467b48Spatrick if (Error Res = JumpToBit(SkipTo)) 51009467b48Spatrick return Res; 51109467b48Spatrick 51209467b48Spatrick return Error::success(); 51309467b48Spatrick } 51409467b48Spatrick 51509467b48Spatrick /// Having read the ENTER_SUBBLOCK abbrevid, and enter the block. 51609467b48Spatrick Error EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); 51709467b48Spatrick ReadBlockEnd()51809467b48Spatrick bool ReadBlockEnd() { 51909467b48Spatrick if (BlockScope.empty()) return true; 52009467b48Spatrick 52109467b48Spatrick // Block tail: 52209467b48Spatrick // [END_BLOCK, <align4bytes>] 52309467b48Spatrick SkipToFourByteBoundary(); 52409467b48Spatrick 52509467b48Spatrick popBlockScope(); 52609467b48Spatrick return false; 52709467b48Spatrick } 52809467b48Spatrick 52909467b48Spatrick private: popBlockScope()53009467b48Spatrick void popBlockScope() { 53109467b48Spatrick CurCodeSize = BlockScope.back().PrevCodeSize; 53209467b48Spatrick 53309467b48Spatrick CurAbbrevs = std::move(BlockScope.back().PrevAbbrevs); 53409467b48Spatrick BlockScope.pop_back(); 53509467b48Spatrick } 53609467b48Spatrick 53709467b48Spatrick //===--------------------------------------------------------------------===// 53809467b48Spatrick // Record Processing 53909467b48Spatrick //===--------------------------------------------------------------------===// 54009467b48Spatrick 54109467b48Spatrick public: 54209467b48Spatrick /// Return the abbreviation for the specified AbbrevId. getAbbrev(unsigned AbbrevID)543*d415bd75Srobert Expected<const BitCodeAbbrev *> getAbbrev(unsigned AbbrevID) { 54409467b48Spatrick unsigned AbbrevNo = AbbrevID - bitc::FIRST_APPLICATION_ABBREV; 54509467b48Spatrick if (AbbrevNo >= CurAbbrevs.size()) 546*d415bd75Srobert return createStringError( 547*d415bd75Srobert std::errc::illegal_byte_sequence, "Invalid abbrev number"); 54809467b48Spatrick return CurAbbrevs[AbbrevNo].get(); 54909467b48Spatrick } 55009467b48Spatrick 55109467b48Spatrick /// Read the current record and discard it, returning the code for the record. 55209467b48Spatrick Expected<unsigned> skipRecord(unsigned AbbrevID); 55309467b48Spatrick 55409467b48Spatrick Expected<unsigned> readRecord(unsigned AbbrevID, 55509467b48Spatrick SmallVectorImpl<uint64_t> &Vals, 55609467b48Spatrick StringRef *Blob = nullptr); 55709467b48Spatrick 55809467b48Spatrick //===--------------------------------------------------------------------===// 55909467b48Spatrick // Abbrev Processing 56009467b48Spatrick //===--------------------------------------------------------------------===// 56109467b48Spatrick Error ReadAbbrevRecord(); 56209467b48Spatrick 56309467b48Spatrick /// Read and return a block info block from the bitstream. If an error was 564*d415bd75Srobert /// encountered, return std::nullopt. 56509467b48Spatrick /// 56609467b48Spatrick /// \param ReadBlockInfoNames Whether to read block/record name information in 56709467b48Spatrick /// the BlockInfo block. Only llvm-bcanalyzer uses this. 568*d415bd75Srobert Expected<std::optional<BitstreamBlockInfo>> 56909467b48Spatrick ReadBlockInfoBlock(bool ReadBlockInfoNames = false); 57009467b48Spatrick 57109467b48Spatrick /// Set the block info to be used by this BitstreamCursor to interpret 57209467b48Spatrick /// abbreviated records. setBlockInfo(BitstreamBlockInfo * BI)57309467b48Spatrick void setBlockInfo(BitstreamBlockInfo *BI) { BlockInfo = BI; } 57409467b48Spatrick }; 57509467b48Spatrick 57609467b48Spatrick } // end llvm namespace 57709467b48Spatrick 57809467b48Spatrick #endif // LLVM_BITSTREAM_BITSTREAMREADER_H 579