aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2013-01-20 02:13:19 +0000
committerChris Lattner <sabre@nondot.org>2013-01-20 02:13:19 +0000
commit5a4251c767adb7a47ad7a53719398ee1342cc400 (patch)
treee6983f469c4292614612673dfdb605a87663ddfc
parent099b636562a83dc9acc6bf36ca32d710ac6d62c9 (diff)
convert the bitstream reader itself and the IR .bc file parser to use the new advance() APIs,
simplifying things and making a bunch of details more private to BitstreamCursor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172947 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp438
-rw-r--r--lib/Bitcode/Reader/BitstreamReader.cpp24
2 files changed, 214 insertions, 248 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index b14250b066..219fc1877d 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -441,29 +441,22 @@ bool BitcodeReader::ParseAttributeBlock() {
// Read all the records.
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of PARAMATTR block");
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("Error at end of PARAMATTR block");
+ case BitstreamEntry::EndBlock:
return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Stream.ReadSubBlockID();
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
- }
-
+
// Read a record.
Record.clear();
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: ignore.
break;
case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...]
@@ -509,32 +502,26 @@ bool BitcodeReader::ParseTypeTableBody() {
// Read all the records for this type table.
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ Error("Error in the type table block");
+ return true;
+ case BitstreamEntry::EndBlock:
if (NumRecords != TypeList.size())
return Error("Invalid type forward reference in TYPE_BLOCK");
- if (Stream.ReadBlockEnd())
- return Error("Error at end of type table block");
return false;
- }
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Stream.ReadSubBlockID();
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
// Read a record.
Record.clear();
Type *ResultTy = 0;
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: return Error("unknown type in type table");
case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
// TYPE_CODE_NUMENTRY contains a count of the number of types in the
@@ -732,28 +719,22 @@ bool BitcodeReader::ParseValueSymbolTable() {
// Read all the records for this value table.
SmallString<128> ValueName;
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of value symbol table block");
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed value symbol table block");
+ case BitstreamEntry::EndBlock:
return false;
- }
- if (Code == bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Stream.ReadSubBlockID();
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
// Read a record.
Record.clear();
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: unknown type.
break;
case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N]
@@ -793,30 +774,24 @@ bool BitcodeReader::ParseMetadata() {
// Read all the records.
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of PARAMATTR block");
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ Error("malformed metadata block");
+ return true;
+ case BitstreamEntry::EndBlock:
return false;
- }
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Stream.ReadSubBlockID();
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
bool IsFunctionLocal = false;
// Read a record.
Record.clear();
- Code = Stream.ReadRecord(Code, Record);
+ unsigned Code = Stream.readRecord(Entry.ID, Record);
switch (Code) {
default: // Default behavior: ignore.
break;
@@ -827,7 +802,7 @@ bool BitcodeReader::ParseMetadata() {
Code = Stream.ReadCode();
// METADATA_NAME is always followed by METADATA_NAMED_NODE.
- unsigned NextBitCode = Stream.ReadRecord(Code, Record);
+ unsigned NextBitCode = Stream.readRecord(Code, Record);
assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode;
// Read named metadata elements.
@@ -954,27 +929,29 @@ bool BitcodeReader::ParseConstants() {
Type *CurTy = Type::getInt32Ty(Context);
unsigned NextCstNo = ValueList.size();
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK)
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed block record in AST file");
+ case BitstreamEntry::EndBlock:
+ if (NextCstNo != ValueList.size())
+ return Error("Invalid constant reference!");
+
+ // Once all the constants have been read, go through and resolve forward
+ // references.
+ ValueList.ResolveConstantForwardRefs();
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
break;
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Stream.ReadSubBlockID();
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
}
// Read a record.
Record.clear();
Value *V = 0;
- unsigned BitCode = Stream.ReadRecord(Code, Record);
+ unsigned BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) {
default: // Default behavior: unknown constant
case bitc::CST_CODE_UNDEF: // UNDEF
@@ -1329,17 +1306,6 @@ bool BitcodeReader::ParseConstants() {
ValueList.AssignValue(V, NextCstNo);
++NextCstNo;
}
-
- if (NextCstNo != ValueList.size())
- return Error("Invalid constant reference!");
-
- if (Stream.ReadBlockEnd())
- return Error("Error at end of constants block");
-
- // Once all the constants have been read, go through and resolve forward
- // references.
- ValueList.ResolveConstantForwardRefs();
- return false;
}
bool BitcodeReader::ParseUseLists() {
@@ -1350,29 +1316,22 @@ bool BitcodeReader::ParseUseLists() {
// Read all the records.
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of use-list table block");
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed use list block");
+ case BitstreamEntry::EndBlock:
return false;
- }
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Stream.ReadSubBlockID();
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
// Read a use list record.
Record.clear();
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: unknown type.
break;
case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD.
@@ -1444,17 +1403,18 @@ bool BitcodeReader::ParseModule(bool Resume) {
std::vector<std::string> GCTable;
// Read all the records for this module.
- while (!Stream.AtEndOfStream()) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of module block");
-
+ while (1) {
+ BitstreamEntry Entry = Stream.advance();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ Error("malformed module block");
+ return true;
+ case BitstreamEntry::EndBlock:
return GlobalCleanup();
- }
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- switch (Stream.ReadSubBlockID()) {
+
+ case BitstreamEntry::SubBlock:
+ switch (Entry.ID) {
default: // Skip unknown content.
if (Stream.SkipBlock())
return Error("Malformed block record");
@@ -1493,7 +1453,7 @@ bool BitcodeReader::ParseModule(bool Resume) {
return true;
SeenFirstFunctionBody = true;
}
-
+
if (RememberAndSkipFunctionBody())
return true;
// For streaming bitcode, suspend parsing when we reach the function
@@ -1513,15 +1473,15 @@ bool BitcodeReader::ParseModule(bool Resume) {
break;
}
continue;
+
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
- }
// Read a record.
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: break; // Default behavior, ignore unknown content.
case bitc::MODULE_CODE_VERSION: { // VERSION: [version#]
if (Record.size() < 1)
@@ -1709,8 +1669,6 @@ bool BitcodeReader::ParseModule(bool Resume) {
}
Record.clear();
}
-
- return Error("Premature end of bitstream");
}
bool BitcodeReader::ParseBitcodeInto(Module *M) {
@@ -1729,47 +1687,55 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) {
// We expect a number of well-defined blocks, though we don't necessarily
// need to understand them all.
- while (!Stream.AtEndOfStream()) {
- unsigned Code = Stream.ReadCode();
-
- if (Code != bitc::ENTER_SUBBLOCK) {
-
- // The ranlib in xcode 4 will align archive members by appending newlines
+ while (1) {
+ if (Stream.AtEndOfStream())
+ return false;
+
+ BitstreamEntry Entry =
+ Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ Error("malformed module file");
+ return true;
+ case BitstreamEntry::EndBlock:
+ return false;
+
+ case BitstreamEntry::SubBlock:
+ switch (Entry.ID) {
+ case bitc::BLOCKINFO_BLOCK_ID:
+ if (Stream.ReadBlockInfoBlock())
+ return Error("Malformed BlockInfoBlock");
+ break;
+ case bitc::MODULE_BLOCK_ID:
+ // Reject multiple MODULE_BLOCK's in a single bitstream.
+ if (TheModule)
+ return Error("Multiple MODULE_BLOCKs in same stream");
+ TheModule = M;
+ if (ParseModule(false))
+ return true;
+ if (LazyStreamer) return false;
+ break;
+ default:
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ }
+ continue;
+ case BitstreamEntry::Record:
+ // There should be no records in the top-level of blocks.
+
+ // The ranlib in Xcode 4 will align archive members by appending newlines
// to the end of them. If this file size is a multiple of 4 but not 8, we
// have to read and ignore these final 4 bytes :-(
- if (Stream.getAbbrevIDWidth() == 2 && Code == 2 &&
+ if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 &&
Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
Stream.AtEndOfStream())
return false;
-
+
return Error("Invalid record at top-level");
}
-
- unsigned BlockID = Stream.ReadSubBlockID();
-
- // We only know the MODULE subblock ID.
- switch (BlockID) {
- case bitc::BLOCKINFO_BLOCK_ID:
- if (Stream.ReadBlockInfoBlock())
- return Error("Malformed BlockInfoBlock");
- break;
- case bitc::MODULE_BLOCK_ID:
- // Reject multiple MODULE_BLOCK's in a single bitstream.
- if (TheModule)
- return Error("Multiple MODULE_BLOCKs in same stream");
- TheModule = M;
- if (ParseModule(false))
- return true;
- if (LazyStreamer) return false;
- break;
- default:
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- break;
- }
}
-
- return false;
}
bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
@@ -1779,32 +1745,22 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
SmallVector<uint64_t, 64> Record;
// Read all the records for this module.
- while (!Stream.AtEndOfStream()) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of module block");
-
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed module block");
+ case BitstreamEntry::EndBlock:
return false;
- }
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- switch (Stream.ReadSubBlockID()) {
- default: // Skip unknown content.
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- break;
- }
- continue;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
// Read a record.
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: break; // Default behavior, ignore unknown content.
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
std::string S;
@@ -1816,8 +1772,6 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
}
Record.clear();
}
-
- return Error("Premature end of bitstream");
}
bool BitcodeReader::ParseTriple(std::string &Triple) {
@@ -1834,28 +1788,32 @@ bool BitcodeReader::ParseTriple(std::string &Triple) {
// We expect a number of well-defined blocks, though we don't necessarily
// need to understand them all.
- while (!Stream.AtEndOfStream()) {
- unsigned Code = Stream.ReadCode();
-
- if (Code != bitc::ENTER_SUBBLOCK)
- return Error("Invalid record at top-level");
-
- unsigned BlockID = Stream.ReadSubBlockID();
-
- // We only know the MODULE subblock ID.
- switch (BlockID) {
- case bitc::MODULE_BLOCK_ID:
- if (ParseModuleTriple(Triple))
+ while (1) {
+ BitstreamEntry Entry = Stream.advance();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ Error("malformed module file");
+ return true;
+ case BitstreamEntry::EndBlock:
+ return false;
+
+ case BitstreamEntry::SubBlock:
+ if (Entry.ID == bitc::MODULE_BLOCK_ID)
+ return ParseModuleTriple(Triple);
+
+ // Ignore other sub-blocks.
+ if (Stream.SkipBlock()) {
+ Error("malformed block record in AST file");
return true;
- break;
- default:
- if (Stream.SkipBlock())
- return Error("Malformed block record");
- break;
+ }
+ continue;
+
+ case BitstreamEntry::Record:
+ Stream.skipRecord(Entry.ID);
+ continue;
}
}
-
- return false;
}
/// ParseMetadataAttachment - Parse metadata attachments.
@@ -1864,20 +1822,23 @@ bool BitcodeReader::ParseMetadataAttachment() {
return Error("Malformed block record");
SmallVector<uint64_t, 64> Record;
- while(1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of PARAMATTR block");
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed metadata block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
break;
}
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
- }
+
// Read a metadata attachment record.
Record.clear();
- switch (Stream.ReadRecord(Code, Record)) {
+ switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: ignore.
break;
case bitc::METADATA_ATTACHMENT: {
@@ -1898,7 +1859,6 @@ bool BitcodeReader::ParseMetadataAttachment() {
}
}
}
- return false;
}
/// ParseFunctionBody - Lazily parse the specified function body block.
@@ -1923,15 +1883,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
// Read all the records.
SmallVector<uint64_t, 64> Record;
while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of function block");
- break;
- }
-
- if (Code == bitc::ENTER_SUBBLOCK) {
- switch (Stream.ReadSubBlockID()) {
+ BitstreamEntry Entry = Stream.advance();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ return Error("Bitcode error in function block");
+ case BitstreamEntry::EndBlock:
+ goto OutOfRecordLoop;
+
+ case BitstreamEntry::SubBlock:
+ switch (Entry.ID) {
default: // Skip unknown content.
if (Stream.SkipBlock())
return Error("Malformed block record");
@@ -1951,17 +1912,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
break;
}
continue;
+
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
}
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
- }
-
+
// Read a record.
Record.clear();
Instruction *I = 0;
- unsigned BitCode = Stream.ReadRecord(Code, Record);
+ unsigned BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) {
default: // Default behavior: reject
return Error("Unknown instruction");
@@ -2738,6 +2698,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
ValueList.AssignValue(I, NextValueNo++);
}
+OutOfRecordLoop:
+
// Check the function list for unresolved values.
if (Argument *A = dyn_cast<Argument>(ValueList.back())) {
if (A->getParent() == 0) {
diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp
index 84d5ca6150..83df57b8fb 100644
--- a/lib/Bitcode/Reader/BitstreamReader.cpp
+++ b/lib/Bitcode/Reader/BitstreamReader.cpp
@@ -306,17 +306,21 @@ bool BitstreamCursor::ReadBlockInfoBlock() {
// Read all the records for this module.
while (1) {
- unsigned Code = ReadCode();
- if (Code == bitc::END_BLOCK)
- return ReadBlockEnd();
- if (Code == bitc::ENTER_SUBBLOCK) {
- ReadSubBlockID();
- if (SkipBlock()) return true;
- continue;
- }
+ BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
+ switch (Entry.Kind) {
+ case llvm::BitstreamEntry::SubBlock: // Handled for us already.
+ case llvm::BitstreamEntry::Error:
+ return true;
+ case llvm::BitstreamEntry::EndBlock:
+ return false;
+ case llvm::BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
// Read abbrev records, associate them with CurBID.
- if (Code == bitc::DEFINE_ABBREV) {
+ if (Entry.ID == bitc::DEFINE_ABBREV) {
if (!CurBlockInfo) return true;
ReadAbbrevRecord();
@@ -330,7 +334,7 @@ bool BitstreamCursor::ReadBlockInfoBlock() {
// Read a record.
Record.clear();
- switch (ReadRecord(Code, Record)) {
+ switch (readRecord(Entry.ID, Record)) {
default: break; // Default behavior, ignore unknown content.
case bitc::BLOCKINFO_CODE_SETBID:
if (Record.size() < 1) return true;