1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

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.

llvm-svn: 172947
This commit is contained in:
Chris Lattner 2013-01-20 02:13:19 +00:00
parent ffaa6ec19b
commit 56672a0fc8
2 changed files with 214 additions and 248 deletions

View File

@ -441,29 +441,22 @@ bool BitcodeReader::ParseAttributeBlock() {
// Read all the records. // Read all the records.
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd()) switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return Error("Error at end of PARAMATTR block"); return Error("Error at end of PARAMATTR block");
case BitstreamEntry::EndBlock:
return false; return false;
} case BitstreamEntry::Record:
// The interesting case.
if (Code == bitc::ENTER_SUBBLOCK) { break;
// 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. // Read a record.
Record.clear(); Record.clear();
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: ignore. default: // Default behavior: ignore.
break; break;
case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...] case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...]
@ -509,32 +502,26 @@ bool BitcodeReader::ParseTypeTableBody() {
// Read all the records for this type table. // Read all the records for this type table.
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
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()) if (NumRecords != TypeList.size())
return Error("Invalid type forward reference in TYPE_BLOCK"); return Error("Invalid type forward reference in TYPE_BLOCK");
if (Stream.ReadBlockEnd())
return Error("Error at end of type table block");
return false; return false;
} case BitstreamEntry::Record:
// The interesting case.
if (Code == bitc::ENTER_SUBBLOCK) { break;
// 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. // Read a record.
Record.clear(); Record.clear();
Type *ResultTy = 0; Type *ResultTy = 0;
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: return Error("unknown type in type table"); default: return Error("unknown type in type table");
case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
// TYPE_CODE_NUMENTRY contains a count of the number of types in the // 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. // Read all the records for this value table.
SmallString<128> ValueName; SmallString<128> ValueName;
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd())
return Error("Error at end of value symbol 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) { switch (Entry.Kind) {
Stream.ReadAbbrevRecord(); case BitstreamEntry::SubBlock: // Handled for us already.
continue; case BitstreamEntry::Error:
return Error("malformed value symbol table block");
case BitstreamEntry::EndBlock:
return false;
case BitstreamEntry::Record:
// The interesting case.
break;
} }
// Read a record. // Read a record.
Record.clear(); Record.clear();
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: unknown type. default: // Default behavior: unknown type.
break; break;
case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N] case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N]
@ -793,30 +774,24 @@ bool BitcodeReader::ParseMetadata() {
// Read all the records. // Read all the records.
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd()) switch (Entry.Kind) {
return Error("Error at end of PARAMATTR block"); case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
Error("malformed metadata block");
return true;
case BitstreamEntry::EndBlock:
return false; return false;
} case BitstreamEntry::Record:
// The interesting case.
if (Code == bitc::ENTER_SUBBLOCK) { break;
// 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;
} }
bool IsFunctionLocal = false; bool IsFunctionLocal = false;
// Read a record. // Read a record.
Record.clear(); Record.clear();
Code = Stream.ReadRecord(Code, Record); unsigned Code = Stream.readRecord(Entry.ID, Record);
switch (Code) { switch (Code) {
default: // Default behavior: ignore. default: // Default behavior: ignore.
break; break;
@ -827,7 +802,7 @@ bool BitcodeReader::ParseMetadata() {
Code = Stream.ReadCode(); Code = Stream.ReadCode();
// METADATA_NAME is always followed by METADATA_NAMED_NODE. // 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; assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode;
// Read named metadata elements. // Read named metadata elements.
@ -954,27 +929,29 @@ bool BitcodeReader::ParseConstants() {
Type *CurTy = Type::getInt32Ty(Context); Type *CurTy = Type::getInt32Ty(Context);
unsigned NextCstNo = ValueList.size(); unsigned NextCstNo = ValueList.size();
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK)
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; 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. // Read a record.
Record.clear(); Record.clear();
Value *V = 0; Value *V = 0;
unsigned BitCode = Stream.ReadRecord(Code, Record); unsigned BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) { switch (BitCode) {
default: // Default behavior: unknown constant default: // Default behavior: unknown constant
case bitc::CST_CODE_UNDEF: // UNDEF case bitc::CST_CODE_UNDEF: // UNDEF
@ -1329,17 +1306,6 @@ bool BitcodeReader::ParseConstants() {
ValueList.AssignValue(V, NextCstNo); ValueList.AssignValue(V, NextCstNo);
++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() { bool BitcodeReader::ParseUseLists() {
@ -1350,29 +1316,22 @@ bool BitcodeReader::ParseUseLists() {
// Read all the records. // Read all the records.
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd()) switch (Entry.Kind) {
return Error("Error at end of use-list table block"); case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return Error("malformed use list block");
case BitstreamEntry::EndBlock:
return false; return false;
} case BitstreamEntry::Record:
// The interesting case.
if (Code == bitc::ENTER_SUBBLOCK) { break;
// 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 use list record. // Read a use list record.
Record.clear(); Record.clear();
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: unknown type. default: // Default behavior: unknown type.
break; break;
case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD. case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD.
@ -1444,17 +1403,18 @@ bool BitcodeReader::ParseModule(bool Resume) {
std::vector<std::string> GCTable; std::vector<std::string> GCTable;
// Read all the records for this module. // Read all the records for this module.
while (!Stream.AtEndOfStream()) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advance();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd())
return Error("Error at end of module block");
switch (Entry.Kind) {
case BitstreamEntry::Error:
Error("malformed module block");
return true;
case BitstreamEntry::EndBlock:
return GlobalCleanup(); return GlobalCleanup();
}
if (Code == bitc::ENTER_SUBBLOCK) { case BitstreamEntry::SubBlock:
switch (Stream.ReadSubBlockID()) { switch (Entry.ID) {
default: // Skip unknown content. default: // Skip unknown content.
if (Stream.SkipBlock()) if (Stream.SkipBlock())
return Error("Malformed block record"); return Error("Malformed block record");
@ -1513,15 +1473,15 @@ bool BitcodeReader::ParseModule(bool Resume) {
break; break;
} }
continue; continue;
case BitstreamEntry::Record:
// The interesting case.
break;
} }
if (Code == bitc::DEFINE_ABBREV) {
Stream.ReadAbbrevRecord();
continue;
}
// Read a record. // Read a record.
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: break; // Default behavior, ignore unknown content. default: break; // Default behavior, ignore unknown content.
case bitc::MODULE_CODE_VERSION: { // VERSION: [version#] case bitc::MODULE_CODE_VERSION: { // VERSION: [version#]
if (Record.size() < 1) if (Record.size() < 1)
@ -1709,8 +1669,6 @@ bool BitcodeReader::ParseModule(bool Resume) {
} }
Record.clear(); Record.clear();
} }
return Error("Premature end of bitstream");
} }
bool BitcodeReader::ParseBitcodeInto(Module *M) { bool BitcodeReader::ParseBitcodeInto(Module *M) {
@ -1729,26 +1687,22 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) {
// We expect a number of well-defined blocks, though we don't necessarily // We expect a number of well-defined blocks, though we don't necessarily
// need to understand them all. // need to understand them all.
while (!Stream.AtEndOfStream()) { while (1) {
unsigned Code = Stream.ReadCode(); if (Stream.AtEndOfStream())
if (Code != bitc::ENTER_SUBBLOCK) {
// 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 &&
Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
Stream.AtEndOfStream())
return false; return false;
return Error("Invalid record at top-level"); BitstreamEntry Entry =
} Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
unsigned BlockID = Stream.ReadSubBlockID(); switch (Entry.Kind) {
case BitstreamEntry::Error:
Error("malformed module file");
return true;
case BitstreamEntry::EndBlock:
return false;
// We only know the MODULE subblock ID. case BitstreamEntry::SubBlock:
switch (BlockID) { switch (Entry.ID) {
case bitc::BLOCKINFO_BLOCK_ID: case bitc::BLOCKINFO_BLOCK_ID:
if (Stream.ReadBlockInfoBlock()) if (Stream.ReadBlockInfoBlock())
return Error("Malformed BlockInfoBlock"); return Error("Malformed BlockInfoBlock");
@ -1767,9 +1721,21 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) {
return Error("Malformed block record"); return Error("Malformed block record");
break; 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 && Entry.ID == 2 &&
Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
Stream.AtEndOfStream())
return false; return false;
return Error("Invalid record at top-level");
}
}
} }
bool BitcodeReader::ParseModuleTriple(std::string &Triple) { bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
@ -1779,32 +1745,22 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
SmallVector<uint64_t, 64> Record; SmallVector<uint64_t, 64> Record;
// Read all the records for this module. // Read all the records for this module.
while (!Stream.AtEndOfStream()) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd())
return Error("Error at end of module block");
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return Error("malformed module block");
case BitstreamEntry::EndBlock:
return false; return false;
} case BitstreamEntry::Record:
// The interesting case.
if (Code == bitc::ENTER_SUBBLOCK) {
switch (Stream.ReadSubBlockID()) {
default: // Skip unknown content.
if (Stream.SkipBlock())
return Error("Malformed block record");
break; break;
} }
continue;
}
if (Code == bitc::DEFINE_ABBREV) {
Stream.ReadAbbrevRecord();
continue;
}
// Read a record. // Read a record.
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: break; // Default behavior, ignore unknown content. default: break; // Default behavior, ignore unknown content.
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
std::string S; std::string S;
@ -1816,8 +1772,6 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
} }
Record.clear(); Record.clear();
} }
return Error("Premature end of bitstream");
} }
bool BitcodeReader::ParseTriple(std::string &Triple) { 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 // We expect a number of well-defined blocks, though we don't necessarily
// need to understand them all. // need to understand them all.
while (!Stream.AtEndOfStream()) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advance();
if (Code != bitc::ENTER_SUBBLOCK) switch (Entry.Kind) {
return Error("Invalid record at top-level"); case BitstreamEntry::Error:
Error("malformed module file");
unsigned BlockID = Stream.ReadSubBlockID();
// We only know the MODULE subblock ID.
switch (BlockID) {
case bitc::MODULE_BLOCK_ID:
if (ParseModuleTriple(Triple))
return true; return true;
break; case BitstreamEntry::EndBlock:
default:
if (Stream.SkipBlock())
return Error("Malformed block record");
break;
}
}
return false; 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;
}
continue;
case BitstreamEntry::Record:
Stream.skipRecord(Entry.ID);
continue;
}
}
} }
/// ParseMetadataAttachment - Parse metadata attachments. /// ParseMetadataAttachment - Parse metadata attachments.
@ -1865,19 +1823,22 @@ bool BitcodeReader::ParseMetadataAttachment() {
SmallVector<uint64_t, 64> Record; SmallVector<uint64_t, 64> Record;
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd()) switch (Entry.Kind) {
return Error("Error at end of PARAMATTR block"); 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; break;
} }
if (Code == bitc::DEFINE_ABBREV) {
Stream.ReadAbbrevRecord();
continue;
}
// Read a metadata attachment record. // Read a metadata attachment record.
Record.clear(); Record.clear();
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: ignore. default: // Default behavior: ignore.
break; break;
case bitc::METADATA_ATTACHMENT: { case bitc::METADATA_ATTACHMENT: {
@ -1898,7 +1859,6 @@ bool BitcodeReader::ParseMetadataAttachment() {
} }
} }
} }
return false;
} }
/// ParseFunctionBody - Lazily parse the specified function body block. /// ParseFunctionBody - Lazily parse the specified function body block.
@ -1923,15 +1883,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
// Read all the records. // Read all the records.
SmallVector<uint64_t, 64> Record; SmallVector<uint64_t, 64> Record;
while (1) { while (1) {
unsigned Code = Stream.ReadCode(); BitstreamEntry Entry = Stream.advance();
if (Code == bitc::END_BLOCK) {
if (Stream.ReadBlockEnd())
return Error("Error at end of function block");
break;
}
if (Code == bitc::ENTER_SUBBLOCK) { switch (Entry.Kind) {
switch (Stream.ReadSubBlockID()) { 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. default: // Skip unknown content.
if (Stream.SkipBlock()) if (Stream.SkipBlock())
return Error("Malformed block record"); return Error("Malformed block record");
@ -1951,17 +1912,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
break; break;
} }
continue; continue;
}
if (Code == bitc::DEFINE_ABBREV) { case BitstreamEntry::Record:
Stream.ReadAbbrevRecord(); // The interesting case.
continue; break;
} }
// Read a record. // Read a record.
Record.clear(); Record.clear();
Instruction *I = 0; Instruction *I = 0;
unsigned BitCode = Stream.ReadRecord(Code, Record); unsigned BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) { switch (BitCode) {
default: // Default behavior: reject default: // Default behavior: reject
return Error("Unknown instruction"); return Error("Unknown instruction");
@ -2738,6 +2698,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
ValueList.AssignValue(I, NextValueNo++); ValueList.AssignValue(I, NextValueNo++);
} }
OutOfRecordLoop:
// Check the function list for unresolved values. // Check the function list for unresolved values.
if (Argument *A = dyn_cast<Argument>(ValueList.back())) { if (Argument *A = dyn_cast<Argument>(ValueList.back())) {
if (A->getParent() == 0) { if (A->getParent() == 0) {

View File

@ -306,17 +306,21 @@ bool BitstreamCursor::ReadBlockInfoBlock() {
// Read all the records for this module. // Read all the records for this module.
while (1) { while (1) {
unsigned Code = ReadCode(); BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
if (Code == bitc::END_BLOCK)
return ReadBlockEnd(); switch (Entry.Kind) {
if (Code == bitc::ENTER_SUBBLOCK) { case llvm::BitstreamEntry::SubBlock: // Handled for us already.
ReadSubBlockID(); case llvm::BitstreamEntry::Error:
if (SkipBlock()) return true; return true;
continue; case llvm::BitstreamEntry::EndBlock:
return false;
case llvm::BitstreamEntry::Record:
// The interesting case.
break;
} }
// Read abbrev records, associate them with CurBID. // Read abbrev records, associate them with CurBID.
if (Code == bitc::DEFINE_ABBREV) { if (Entry.ID == bitc::DEFINE_ABBREV) {
if (!CurBlockInfo) return true; if (!CurBlockInfo) return true;
ReadAbbrevRecord(); ReadAbbrevRecord();
@ -330,7 +334,7 @@ bool BitstreamCursor::ReadBlockInfoBlock() {
// Read a record. // Read a record.
Record.clear(); Record.clear();
switch (ReadRecord(Code, Record)) { switch (readRecord(Entry.ID, Record)) {
default: break; // Default behavior, ignore unknown content. default: break; // Default behavior, ignore unknown content.
case bitc::BLOCKINFO_CODE_SETBID: case bitc::BLOCKINFO_CODE_SETBID:
if (Record.size() < 1) return true; if (Record.size() < 1) return true;