================
@@ -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
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to