[llvm-branch-commits] [Remarks] BitstreamRemarkParser: Refactor error handling (PR #156511)
Jon Roelofs via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 15 06:44:31 PDT 2025
================
@@ -52,171 +91,132 @@ static Error parseRecord(BitstreamMetaParserHelper &Parser, unsigned Code) {
switch (*RecordID) {
case RECORD_META_CONTAINER_INFO: {
if (Record.size() != 2)
- return malformedRecord("BLOCK_META", "RECORD_META_CONTAINER_INFO");
- Parser.ContainerVersion = Record[0];
- Parser.ContainerType = Record[1];
+ return malformedRecord(MetaContainerInfoName);
+ Container = {Record[0], Record[1]};
+ // Error immediately if container version is outdated, so the user sees an
+ // explanation instead of a parser error.
+ if (Container->Version != CurrentContainerVersion) {
+ return ::error(
+ "Unsupported remark container version (expected: {}, read: {}). "
+ "Please upgrade/downgrade your toolchain to read this container.",
+ CurrentContainerVersion, Container->Version);
+ }
break;
}
case RECORD_META_REMARK_VERSION: {
if (Record.size() != 1)
- return malformedRecord("BLOCK_META", "RECORD_META_REMARK_VERSION");
- Parser.RemarkVersion = Record[0];
+ return malformedRecord(MetaRemarkVersionName);
+ RemarkVersion = Record[0];
+ // Error immediately if remark version is outdated, so the user sees an
+ // explanation instead of a parser error.
+ if (*RemarkVersion != CurrentRemarkVersion) {
+ return ::error(
+ "Unsupported remark version in container (expected: {}, read: {}). "
+ "Please upgrade/downgrade your toolchain to read this container.",
+ CurrentRemarkVersion, *RemarkVersion);
+ }
break;
}
case RECORD_META_STRTAB: {
if (Record.size() != 0)
- return malformedRecord("BLOCK_META", "RECORD_META_STRTAB");
- Parser.StrTabBuf = Blob;
+ return malformedRecord(MetaStrTabName);
+ StrTabBuf = Blob;
break;
}
case RECORD_META_EXTERNAL_FILE: {
if (Record.size() != 0)
- return malformedRecord("BLOCK_META", "RECORD_META_EXTERNAL_FILE");
- Parser.ExternalFilePath = Blob;
+ return malformedRecord(MetaExternalFileName);
+ ExternalFilePath = Blob;
break;
}
default:
- return unknownRecord("BLOCK_META", *RecordID);
+ return unknownRecord(*RecordID);
}
return Error::success();
}
-BitstreamRemarkParserHelper::BitstreamRemarkParserHelper(
- BitstreamCursor &Stream)
- : Stream(Stream) {}
-
-/// Parse a record and fill in the fields in the parser.
-static Error parseRecord(BitstreamRemarkParserHelper &Parser, unsigned Code) {
- BitstreamCursor &Stream = Parser.Stream;
- // Note: 5 is used here because it's the max number of fields we have per
- // record.
- SmallVector<uint64_t, 5> Record;
- StringRef Blob;
- Expected<unsigned> RecordID = Stream.readRecord(Code, Record, &Blob);
- if (!RecordID)
- return RecordID.takeError();
+Error BitstreamRemarkParserHelper::parseRecord(unsigned Code) {
+ Record.clear();
+ Expected<unsigned> MaybeRecordID =
+ Stream.readRecord(Code, Record, &RecordBlob);
+ if (!MaybeRecordID)
+ return MaybeRecordID.takeError();
+ RecordID = *MaybeRecordID;
+ return handleRecord();
+}
- switch (*RecordID) {
+Error BitstreamRemarkParserHelper::handleRecord() {
+ switch (RecordID) {
case RECORD_REMARK_HEADER: {
if (Record.size() != 4)
- return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_HEADER");
- Parser.Type = Record[0];
- Parser.RemarkNameIdx = Record[1];
- Parser.PassNameIdx = Record[2];
- Parser.FunctionNameIdx = Record[3];
+ return malformedRecord(RemarkHeaderName);
+ Type = Record[0];
+ RemarkNameIdx = Record[1];
+ PassNameIdx = Record[2];
+ FunctionNameIdx = Record[3];
break;
}
case RECORD_REMARK_DEBUG_LOC: {
if (Record.size() != 3)
- return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_DEBUG_LOC");
- Parser.SourceFileNameIdx = Record[0];
- Parser.SourceLine = Record[1];
- Parser.SourceColumn = Record[2];
+ return malformedRecord(RemarkDebugLocName);
+ Loc = {Record[0], Record[1], Record[2]};
break;
}
case RECORD_REMARK_HOTNESS: {
if (Record.size() != 1)
- return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_HOTNESS");
- Parser.Hotness = Record[0];
+ return malformedRecord(RemarkHotnessName);
+ Hotness = Record[0];
break;
}
case RECORD_REMARK_ARG_WITH_DEBUGLOC: {
if (Record.size() != 5)
- return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_ARG_WITH_DEBUGLOC");
- // Create a temporary argument. Use that as a valid memory location for this
- // argument entry.
- Parser.TmpArgs.emplace_back();
- Parser.TmpArgs.back().KeyIdx = Record[0];
- Parser.TmpArgs.back().ValueIdx = Record[1];
- Parser.TmpArgs.back().SourceFileNameIdx = Record[2];
- Parser.TmpArgs.back().SourceLine = Record[3];
- Parser.TmpArgs.back().SourceColumn = Record[4];
- Parser.Args =
- ArrayRef<BitstreamRemarkParserHelper::Argument>(Parser.TmpArgs);
+ return malformedRecord(RemarkArgWithDebugLocName);
+ auto &Arg = Args.emplace_back(Record[0], Record[1]);
+ Arg.Loc = {Record[2], Record[3], Record[4]};
break;
}
case RECORD_REMARK_ARG_WITHOUT_DEBUGLOC: {
if (Record.size() != 2)
- return malformedRecord("BLOCK_REMARK",
- "RECORD_REMARK_ARG_WITHOUT_DEBUGLOC");
- // Create a temporary argument. Use that as a valid memory location for this
- // argument entry.
- Parser.TmpArgs.emplace_back();
- Parser.TmpArgs.back().KeyIdx = Record[0];
- Parser.TmpArgs.back().ValueIdx = Record[1];
- Parser.Args =
- ArrayRef<BitstreamRemarkParserHelper::Argument>(Parser.TmpArgs);
+ return malformedRecord(RemarkArgWithoutDebugLocName);
+ Args.emplace_back(Record[0], Record[1]);
break;
}
default:
- return unknownRecord("BLOCK_REMARK", *RecordID);
+ return unknownRecord(RecordID);
}
return Error::success();
}
-template <typename T>
-static Error parseBlock(T &ParserHelper, unsigned BlockID,
- const char *BlockName) {
- BitstreamCursor &Stream = ParserHelper.Stream;
- Expected<BitstreamEntry> Next = Stream.advance();
- if (!Next)
- return Next.takeError();
- if (Next->Kind != BitstreamEntry::SubBlock || Next->ID != BlockID)
- return createStringError(
- std::make_error_code(std::errc::illegal_byte_sequence),
- "Error while parsing %s: expecting [ENTER_SUBBLOCK, %s, ...].",
- BlockName, BlockName);
- if (Stream.EnterSubBlock(BlockID))
- return createStringError(
- std::make_error_code(std::errc::illegal_byte_sequence),
- "Error while entering %s.", BlockName);
-
- // Stop when there is nothing to read anymore or when we encounter an
- // END_BLOCK.
- while (!Stream.AtEndOfStream()) {
- Next = Stream.advance();
- if (!Next)
- return Next.takeError();
- switch (Next->Kind) {
- case BitstreamEntry::EndBlock:
- return Error::success();
- case BitstreamEntry::Error:
- case BitstreamEntry::SubBlock:
- return createStringError(
- std::make_error_code(std::errc::illegal_byte_sequence),
- "Error while parsing %s: expecting records.", BlockName);
- case BitstreamEntry::Record:
- if (Error E = parseRecord(ParserHelper, Next->ID))
- return E;
- continue;
- }
- }
- // If we're here, it means we didn't get an END_BLOCK yet, but we're at the
- // end of the stream. In this case, error.
- return createStringError(
- std::make_error_code(std::errc::illegal_byte_sequence),
- "Error while parsing %s: unterminated block.", BlockName);
-}
+Error BitstreamRemarkParserHelper::parseNext() {
+ Type.reset();
+ RemarkNameIdx.reset();
+ PassNameIdx.reset();
+ FunctionNameIdx.reset();
+ Hotness.reset();
+ Loc.reset();
+ Args.clear();
-Error BitstreamMetaParserHelper::parse() {
- return parseBlock(*this, META_BLOCK_ID, "META_BLOCK");
-}
-
-Error BitstreamRemarkParserHelper::parse() {
- return parseBlock(*this, REMARK_BLOCK_ID, "REMARK_BLOCK");
+ if (Error E = expectBlock())
+ return E;
+ return parseBlock();
}
BitstreamParserHelper::BitstreamParserHelper(StringRef Buffer)
: Stream(Buffer) {}
-Expected<std::array<char, 4>> BitstreamParserHelper::parseMagic() {
+Error BitstreamParserHelper::expectMagic() {
std::array<char, 4> Result;
- for (unsigned i = 0; i < 4; ++i)
+ for (unsigned I = 0; I < 4; ++I)
if (Expected<unsigned> R = Stream.Read(8))
- Result[i] = *R;
+ Result[I] = *R;
else
return R.takeError();
- return Result;
+
+ StringRef MagicNumber{Result.data(), Result.size()};
+ if (MagicNumber != remarks::ContainerMagic)
+ return error("Unknown magic number: expecting {}, got {}.",
+ remarks::ContainerMagic, MagicNumber);
----------------
jroelofs wrote:
ok, fair.
https://github.com/llvm/llvm-project/pull/156511
More information about the llvm-branch-commits
mailing list