aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/Reader/BitstreamReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/Reader/BitstreamReader.cpp')
-rw-r--r--lib/Bitcode/Reader/BitstreamReader.cpp68
1 files changed, 49 insertions, 19 deletions
diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp
index a103fbdf4a93..60360d2ef78f 100644
--- a/lib/Bitcode/Reader/BitstreamReader.cpp
+++ b/lib/Bitcode/Reader/BitstreamReader.cpp
@@ -32,7 +32,7 @@ bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
// Add the abbrevs specific to this block to the CurAbbrevs list.
if (const BitstreamReader::BlockInfo *Info =
- BitStream->getBlockInfo(BlockID)) {
+ getBitStreamReader()->getBlockInfo(BlockID)) {
CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
Info->Abbrevs.end());
}
@@ -131,8 +131,25 @@ void BitstreamCursor::skipRecord(unsigned AbbrevID) {
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
// Read all the elements.
- for (; NumElts; --NumElts)
- skipAbbreviatedField(*this, EltEnc);
+ // Decode the value as we are commanded.
+ switch (EltEnc.getEncoding()) {
+ default:
+ report_fatal_error("Array element type can't be an Array or a Blob");
+ case BitCodeAbbrevOp::Fixed:
+ assert((unsigned)Op.getEncodingData() <= MaxChunkSize);
+ for (; NumElts; --NumElts)
+ Read((unsigned)EltEnc.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::VBR:
+ assert((unsigned)Op.getEncodingData() <= MaxChunkSize);
+ for (; NumElts; --NumElts)
+ ReadVBR64((unsigned)EltEnc.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::Char6:
+ for (; NumElts; --NumElts)
+ Read(6);
+ break;
+ }
continue;
}
@@ -147,7 +164,7 @@ void BitstreamCursor::skipRecord(unsigned AbbrevID) {
// If this would read off the end of the bitcode file, just set the
// record to empty and return.
if (!canSkipToPos(NewEnd/8)) {
- NextChar = BitStream->getBitcodeBytes().getExtent();
+ skipToEnd();
break;
}
@@ -206,13 +223,23 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
if (!EltEnc.isEncoding())
report_fatal_error(
"Array element type has to be an encoding of a type");
- if (EltEnc.getEncoding() == BitCodeAbbrevOp::Array ||
- EltEnc.getEncoding() == BitCodeAbbrevOp::Blob)
- report_fatal_error("Array element type can't be an Array or a Blob");
// Read all the elements.
- for (; NumElts; --NumElts)
- Vals.push_back(readAbbreviatedField(*this, EltEnc));
+ switch (EltEnc.getEncoding()) {
+ default:
+ report_fatal_error("Array element type can't be an Array or a Blob");
+ case BitCodeAbbrevOp::Fixed:
+ for (; NumElts; --NumElts)
+ Vals.push_back(Read((unsigned)EltEnc.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::VBR:
+ for (; NumElts; --NumElts)
+ Vals.push_back(ReadVBR64((unsigned)EltEnc.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::Char6:
+ for (; NumElts; --NumElts)
+ Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
+ }
continue;
}
@@ -229,13 +256,15 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
// record to empty and return.
if (!canSkipToPos(NewEnd/8)) {
Vals.append(NumElts, 0);
- NextChar = BitStream->getBitcodeBytes().getExtent();
+ skipToEnd();
break;
}
- // Otherwise, inform the streamer that we need these bytes in memory.
- const char *Ptr = (const char*)
- BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts);
+ // Otherwise, inform the streamer that we need these bytes in memory. Skip
+ // over tail padding first, in case jumping to NewEnd invalidates the Blob
+ // pointer.
+ JumpToBit(NewEnd);
+ const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts);
// If we can return a reference to the data, do so to avoid copying it.
if (Blob) {
@@ -245,8 +274,6 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
for (; NumElts; --NumElts)
Vals.push_back((unsigned char)*Ptr++);
}
- // Skip over tail padding.
- JumpToBit(NewEnd);
}
return Code;
@@ -293,7 +320,7 @@ void BitstreamCursor::ReadAbbrevRecord() {
bool BitstreamCursor::ReadBlockInfoBlock() {
// If this is the second stream to get to the block info block, skip it.
- if (BitStream->hasBlockInfoRecords())
+ if (getBitStreamReader()->hasBlockInfoRecords())
return SkipBlock();
if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
@@ -334,11 +361,13 @@ bool BitstreamCursor::ReadBlockInfoBlock() {
default: break; // Default behavior, ignore unknown content.
case bitc::BLOCKINFO_CODE_SETBID:
if (Record.size() < 1) return true;
- CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
+ CurBlockInfo =
+ &getBitStreamReader()->getOrCreateBlockInfo((unsigned)Record[0]);
break;
case bitc::BLOCKINFO_CODE_BLOCKNAME: {
if (!CurBlockInfo) return true;
- if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
+ if (getBitStreamReader()->isIgnoringBlockInfoNames())
+ break; // Ignore name.
std::string Name;
for (unsigned i = 0, e = Record.size(); i != e; ++i)
Name += (char)Record[i];
@@ -347,7 +376,8 @@ bool BitstreamCursor::ReadBlockInfoBlock() {
}
case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
if (!CurBlockInfo) return true;
- if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
+ if (getBitStreamReader()->isIgnoringBlockInfoNames())
+ break; // Ignore name.
std::string Name;
for (unsigned i = 1, e = Record.size(); i != e; ++i)
Name += (char)Record[i];