LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) { if (Stream.EnterSubBlock(lfort::serialized_diags::BLOCK_META)) { reportInvalidFile("Malformed metadata block"); return Failure; } bool versionChecked = false; while (true) { unsigned blockOrCode = 0; StreamResult Res = readToNextRecordOrBlock(Stream, "Metadata Block", blockOrCode); switch(Res) { case Read_EndOfStream: llvm_unreachable("EndOfStream handled by readToNextRecordOrBlock"); case Read_Failure: return Failure; case Read_Record: break; case Read_BlockBegin: if (Stream.SkipBlock()) { reportInvalidFile("Malformed metadata block"); return Failure; } case Read_BlockEnd: if (!versionChecked) { reportInvalidFile("Diagnostics file does not contain version" " information"); return Failure; } return Success; } RecordData Record; const char *Blob; unsigned BlobLen; unsigned recordID = Stream.ReadRecord(blockOrCode, Record, &Blob, &BlobLen); if (recordID == serialized_diags::RECORD_VERSION) { if (Record.size() < 1) { reportInvalidFile("malformed VERSION identifier in diagnostics file"); return Failure; } if (Record[0] > MaxSupportedVersion) { reportInvalidFile("diagnosics file is a newer version than the one " "supported"); return Failure; } versionChecked = true; } } }
LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream, CXDiagnosticSetImpl &Diags, CXLoadedDiagnosticSetImpl &TopDiags){ if (Stream.EnterSubBlock(lfort::serialized_diags::BLOCK_DIAG)) { reportInvalidFile("malformed diagnostic block"); return Failure; } OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic()); RecordData Record; while (true) { unsigned blockOrCode = 0; StreamResult Res = readToNextRecordOrBlock(Stream, "Diagnostic Block", blockOrCode); switch (Res) { case Read_EndOfStream: llvm_unreachable("EndOfStream handled in readToNextRecordOrBlock"); case Read_Failure: return Failure; case Read_BlockBegin: { // The only blocks we care about are subdiagnostics. if (blockOrCode != serialized_diags::BLOCK_DIAG) { if (!Stream.SkipBlock()) { reportInvalidFile("Invalid subblock in Diagnostics block"); return Failure; } } else if (readDiagnosticBlock(Stream, D->getChildDiagnostics(), TopDiags)) { return Failure; } continue; } case Read_BlockEnd: Diags.appendDiagnostic(D.take()); return Success; case Read_Record: break; } // Read the record. Record.clear(); const char *BlobStart = 0; unsigned BlobLen = 0; unsigned recID = Stream.ReadRecord(blockOrCode, Record, BlobStart, BlobLen); if (recID < serialized_diags::RECORD_FIRST || recID > serialized_diags::RECORD_LAST) continue; switch ((serialized_diags::RecordIDs)recID) { case serialized_diags::RECORD_VERSION: continue; case serialized_diags::RECORD_CATEGORY: if (readString(TopDiags, TopDiags.Categories, "category", Record, BlobStart, BlobLen, /* allowEmptyString */ true)) return Failure; continue; case serialized_diags::RECORD_DIAG_FLAG: if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record, BlobStart, BlobLen)) return Failure; continue; case serialized_diags::RECORD_FILENAME: { if (readString(TopDiags, TopDiags.FileNames, "filename", Record, BlobStart, BlobLen)) return Failure; if (Record.size() < 3) { reportInvalidFile("Invalid file entry"); return Failure; } const FileEntry *FE = TopDiags.FakeFiles.getVirtualFile(TopDiags.FileNames[Record[0]], /* size */ Record[1], /* time */ Record[2]); TopDiags.Files[Record[0]] = FE; continue; } case serialized_diags::RECORD_SOURCE_RANGE: { CXSourceRange SR; if (readRange(TopDiags, Record, 0, SR)) return Failure; D->Ranges.push_back(SR); continue; } case serialized_diags::RECORD_FIXIT: { CXSourceRange SR; if (readRange(TopDiags, Record, 0, SR)) return Failure; llvm::StringRef RetStr; if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen, /* allowEmptyString */ true)) return Failure; D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false))); continue; } case serialized_diags::RECORD_DIAG: { D->severity = Record[0]; unsigned offset = 1; if (readLocation(TopDiags, Record, offset, D->DiagLoc)) return Failure; D->category = Record[offset++]; unsigned diagFlag = Record[offset++]; D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : ""; D->CategoryText = D->category ? TopDiags.Categories[D->category] : ""; D->Spelling = TopDiags.makeString(BlobStart, BlobLen); continue; } } } }