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
This commit is contained in:
Chris Lattner 2013-01-20 02:13:19 +00:00
parent 099b636562
commit 5a4251c767
2 changed files with 214 additions and 248 deletions

View File

@ -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) {

View File

@ -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;