15 #ifndef LLVM_BITCODE_BITSTREAMREADER_H
16 #define LLVM_BITCODE_BITSTREAMREADER_H
37 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>>
Abbrevs;
43 std::unique_ptr<MemoryObject> BitcodeBytes;
45 std::vector<BlockInfo> BlockInfoRecords;
49 bool IgnoreBlockInfoNames;
58 : IgnoreBlockInfoNames(
true) {
63 : BitcodeBytes(std::move(BitcodeBytes)), IgnoreBlockInfoNames(
true) {}
66 *
this = std::move(
Other);
70 BitcodeBytes = std::move(
Other.BitcodeBytes);
73 IgnoreBlockInfoNames =
Other.IgnoreBlockInfoNames;
77 void init(
const unsigned char *Start,
const unsigned char *End) {
78 assert(((End-Start) & 3) == 0 &&
"Bitcode stream not a multiple of 4 bytes");
101 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
102 return &BlockInfoRecords.back();
104 for (
unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
106 if (BlockInfoRecords[i].BlockID == BlockID)
107 return &BlockInfoRecords[i];
116 BlockInfoRecords.emplace_back();
117 BlockInfoRecords.back().BlockID = BlockID;
118 return BlockInfoRecords.back();
127 BlockInfoRecords = std::move(
Other.BlockInfoRecords);
176 typedef size_t word_t;
181 unsigned BitsInCurWord;
185 unsigned CurCodeSize;
188 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs;
191 unsigned PrevCodeSize;
192 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs;
193 explicit Block(
unsigned PCS) : PrevCodeSize(PCS) {}
222 static_cast<uint64_t>(pos - 1));
226 if (BitsInCurWord != 0)
229 return Size == NextChar;
231 return BitsInCurWord == 0;
239 return NextChar*CHAR_BIT - BitsInCurWord;
303 size_t ByteNo = size_t(BitNo/8) & ~(
sizeof(word_t)-1);
304 unsigned WordBitNo =
unsigned(BitNo & (
sizeof(word_t)*8-1));
317 if (Size != 0 && NextChar >= Size)
321 uint8_t Array[
sizeof(word_t)] = {0};
327 if (BytesRead == 0) {
333 support::endian::read<word_t, support::little, support::unaligned>(
335 NextChar += BytesRead;
336 BitsInCurWord = BytesRead * 8;
339 word_t
Read(
unsigned NumBits) {
342 assert(NumBits && NumBits <= BitsInWord &&
343 "Cannot return zero or more than BitsInWord bits!");
345 static const unsigned Mask =
sizeof(word_t) > 4 ? 0x3f : 0x1f;
348 if (BitsInCurWord >= NumBits) {
349 word_t R = CurWord & (~word_t(0) >> (BitsInWord - NumBits));
352 CurWord >>= (NumBits & Mask);
354 BitsInCurWord -= NumBits;
358 word_t R = BitsInCurWord ? CurWord : 0;
359 unsigned BitsLeft = NumBits - BitsInCurWord;
364 if (BitsLeft > BitsInCurWord)
367 word_t
R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft));
370 CurWord >>= (BitsLeft & Mask);
372 BitsInCurWord -= BitsLeft;
374 R |= R2 << (NumBits - BitsLeft);
380 uint32_t Piece =
Read(NumBits);
381 if ((Piece & (1U << (NumBits-1))) == 0)
385 unsigned NextBit = 0;
387 Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
389 if ((Piece & (1U << (NumBits-1))) == 0)
392 NextBit += NumBits-1;
393 Piece =
Read(NumBits);
400 uint32_t Piece =
Read(NumBits);
401 if ((Piece & (1U << (NumBits-1))) == 0)
402 return uint64_t(Piece);
405 unsigned NextBit = 0;
407 Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit;
409 if ((Piece & (1U << (NumBits-1))) == 0)
412 NextBit += NumBits-1;
413 Piece =
Read(NumBits);
418 void SkipToFourByteBoundary() {
421 if (
sizeof(word_t) > 4 &&
422 BitsInCurWord >= 32) {
423 CurWord >>= BitsInCurWord-32;
433 return Read(CurCodeSize);
451 SkipToFourByteBoundary();
466 bool EnterSubBlock(
unsigned BlockID,
unsigned *NumWordsP =
nullptr);
469 if (BlockScope.
empty())
return true;
473 SkipToFourByteBoundary();
481 void popBlockScope() {
482 CurCodeSize = BlockScope.
back().PrevCodeSize;
484 CurAbbrevs = std::move(BlockScope.
back().PrevAbbrevs);
496 if (AbbrevNo >= CurAbbrevs.size())
498 return CurAbbrevs[AbbrevNo].get();
BitstreamReader & operator=(BitstreamReader &&Other)
const BitCodeAbbrev * getAbbrev(unsigned AbbrevID)
Return the abbreviation for the specified AbbrevId.
void init(BitstreamReader *R)
Interface to data which might be streamed.
This class is used to read from an LLVM bitcode stream, maintaining information that is global to dec...
BitCodeAbbrev - This class represents an abbreviation record.
static const size_t MaxChunkSize
bool hasBlockInfoRecords() const
Return true if we've already read and processed the block info block for this Bitstream.
BitstreamCursor(BitstreamReader &R)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
uint64_t GetCurrentBitNo() const
Return the bit # of the bit we are reading.
bool canSkipToPos(size_t pos) const
const BlockInfo * getBlockInfo(unsigned BlockID) const
If there is block info for the specified ID, return it, otherwise return null.
enum llvm::BitstreamEntry::@28 Kind
std::vector< std::pair< unsigned, std::string > > RecordNames
virtual uint64_t readBytes(uint8_t *Buf, uint64_t Size, uint64_t Address) const =0
Tries to read a contiguous range of bytes from the region, up to the end of the region.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
BlockInfo & getOrCreateBlockInfo(unsigned BlockID)
static BitstreamEntry getSubBlock(unsigned ID)
BitstreamEntry advanceSkippingSubblocks(unsigned Flags=0)
This is a convenience function for clients that don't expect any subblocks.
If this flag is used, abbrev entries are returned just like normal records.
BitstreamReader * getBitStreamReader()
This represents a position within a bitcode file.
uint64_t ReadVBR64(unsigned NumBits)
If this flag is used, the advance() method does not automatically pop the block scope when the end of...
void init(const unsigned char *Start, const unsigned char *End)
bool SkipBlock()
Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body of this block...
MemoryObject & getBitcodeBytes()
unsigned ReadSubBlockID()
Having read the ENTER_SUBBLOCK code, read the BlockID for the block.
This contains information emitted to BLOCKINFO_BLOCK blocks.
uint32_t ReadVBR(unsigned NumBits)
BitstreamReader(const unsigned char *Start, const unsigned char *End)
std::vector< IntrusiveRefCntPtr< BitCodeAbbrev > > Abbrevs
When advancing through a bitstream cursor, each advance can discover a few different kinds of entries...
unsigned readRecord(unsigned AbbrevID, SmallVectorImpl< uint64_t > &Vals, StringRef *Blob=nullptr)
word_t Read(unsigned NumBits)
virtual bool isValidAddress(uint64_t address) const =0
Returns true if the address is within the object (i.e.
void skipRecord(unsigned AbbrevID)
Read the current record and discard it.
void CollectBlockInfoNames()
This is called by clients that want block/record name information.
DEFINE_ABBREV - Defines an abbrev for the current block.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
BitstreamReader(std::unique_ptr< MemoryObject > BitcodeBytes)
void takeBlockInfo(BitstreamReader &&Other)
Takes block info from the other bitstream reader.
bool isIgnoringBlockInfoNames()
const BitstreamReader * getBitStreamReader() const
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP=nullptr)
Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true if the block has an error...
static BitstreamEntry getEndBlock()
static BitstreamEntry getRecord(unsigned AbbrevID)
void JumpToBit(uint64_t BitNo)
Reset the stream to the specified bit number.
static BitstreamEntry getError()
BitstreamEntry advance(unsigned Flags=0)
Advance the current bitstream, returning the next entry in the stream.
StringRef - Represent a constant reference to a string, i.e.
MemoryObject * getNonStreamedMemoryObject(const unsigned char *Start, const unsigned char *End)
BitstreamReader(BitstreamReader &&Other)
unsigned getAbbrevIDWidth() const
Return the number of bits used to encode an abbrev #.
bool ReadBlockInfoBlock()