static bool enterTopLevelModuleBlock(llvm::BitstreamCursor &cursor, unsigned ID, bool shouldReadBlockInfo = true) { auto next = cursor.advance(); if (next.Kind != llvm::BitstreamEntry::SubBlock) return false; if (next.ID == llvm::bitc::BLOCKINFO_BLOCK_ID) { if (shouldReadBlockInfo) { if (cursor.ReadBlockInfoBlock()) return false; } else { if (cursor.SkipBlock()) return false; } return enterTopLevelModuleBlock(cursor, ID, false); } if (next.ID != ID) return false; cursor.EnterSubBlock(ID); return true; }
StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream, llvm::StringRef errorContext, unsigned &blockOrRecordID, bool atTopLevel) { blockOrRecordID = 0; while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); // Handle the top-level specially. if (atTopLevel) { if (Code == llvm::bitc::ENTER_SUBBLOCK) { unsigned BlockID = Stream.ReadSubBlockID(); if (BlockID == llvm::bitc::BLOCKINFO_BLOCK_ID) { if (Stream.ReadBlockInfoBlock()) { reportInvalidFile("Malformed BlockInfoBlock in diagnostics file"); return Read_Failure; } continue; } blockOrRecordID = BlockID; return Read_BlockBegin; } reportInvalidFile("Only blocks can appear at the top of a " "diagnostic file"); return Read_Failure; } switch ((llvm::bitc::FixedAbbrevIDs)Code) { case llvm::bitc::ENTER_SUBBLOCK: blockOrRecordID = Stream.ReadSubBlockID(); return Read_BlockBegin; case llvm::bitc::END_BLOCK: if (Stream.ReadBlockEnd()) { reportInvalidFile("Cannot read end of block"); return Read_Failure; } return Read_BlockEnd; case llvm::bitc::DEFINE_ABBREV: Stream.ReadAbbrevRecord(); continue; case llvm::bitc::UNABBREV_RECORD: reportInvalidFile("Diagnostics file should have no unabbreviated " "records"); return Read_Failure; default: // We found a record. blockOrRecordID = Code; return Read_Record; } } if (atTopLevel) return Read_EndOfStream; reportInvalidFile(Twine("Premature end of diagnostics file within ").str() + errorContext.str()); return Read_Failure; }