//===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines classes for handling the YAML representation of CodeView
// Debug Info.
//
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::CodeViewYAML;
using namespace llvm::CodeViewYAML::detail;
using namespace llvm::yaml;

LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock)
LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite)
LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport)
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)

LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)

LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport)
LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData)
LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport)
LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem)
LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry)
LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry)
LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry)
LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock)
LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite)

namespace llvm {
namespace CodeViewYAML {
namespace detail {

struct YAMLSubsectionBase {
  explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {}
  virtual ~YAMLSubsectionBase() = default;

  virtual void map(IO &IO) = 0;
  virtual std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const = 0;

  DebugSubsectionKind Kind;
};

} // end namespace detail
} // end namespace CodeViewYAML
} // end namespace llvm

namespace {

struct YAMLChecksumsSubsection : public YAMLSubsectionBase {
  YAMLChecksumsSubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
                         const DebugChecksumsSubsectionRef &FC);

  std::vector<SourceFileChecksumEntry> Checksums;
};

struct YAMLLinesSubsection : public YAMLSubsectionBase {
  YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLLinesSubsection>>
  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
                         const DebugChecksumsSubsectionRef &Checksums,
                         const DebugLinesSubsectionRef &Lines);

  SourceLineInfo Lines;
};

struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase {
  YAMLInlineeLinesSubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
                         const DebugChecksumsSubsectionRef &Checksums,
                         const DebugInlineeLinesSubsectionRef &Lines);

  InlineeInfo InlineeLines;
};

struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase {
  YAMLCrossModuleExportsSubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
  fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);

  std::vector<CrossModuleExport> Exports;
};

struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase {
  YAMLCrossModuleImportsSubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
                         const DebugCrossModuleImportsSubsectionRef &Imports);

  std::vector<YAMLCrossModuleImport> Imports;
};

struct YAMLSymbolsSubsection : public YAMLSubsectionBase {
  YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLSymbolsSubsection>>
  fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);

  std::vector<CodeViewYAML::SymbolRecord> Symbols;
};

struct YAMLStringTableSubsection : public YAMLSubsectionBase {
  YAMLStringTableSubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLStringTableSubsection>>
  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);

  std::vector<StringRef> Strings;
};

struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
  YAMLFrameDataSubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLFrameDataSubsection>>
  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
                         const DebugFrameDataSubsectionRef &Frames);

  std::vector<YAMLFrameData> Frames;
};

struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
  YAMLCoffSymbolRVASubsection()
      : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}

  void map(IO &IO) override;
  std::shared_ptr<DebugSubsection>
  toCodeViewSubsection(BumpPtrAllocator &Allocator,
                       const codeview::StringsAndChecksums &SC) const override;
  static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
  fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);

  std::vector<uint32_t> RVAs;
};

} // end anonymous namespace

void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
  io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
  io.enumFallback<Hex16>(Flags);
}

void ScalarEnumerationTraits<FileChecksumKind>::enumeration(
    IO &io, FileChecksumKind &Kind) {
  io.enumCase(Kind, "None", FileChecksumKind::None);
  io.enumCase(Kind, "MD5", FileChecksumKind::MD5);
  io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1);
  io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256);
}

void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
                                              void *ctx, raw_ostream &Out) {
  StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
                  Value.Bytes.size());
  Out << toHex(Bytes);
}

StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
                                                  HexFormattedString &Value) {
  std::string H = fromHex(Scalar);
  Value.Bytes.assign(H.begin(), H.end());
  return StringRef();
}

void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) {
  IO.mapRequired("Offset", Obj.Offset);
  IO.mapRequired("LineStart", Obj.LineStart);
  IO.mapRequired("IsStatement", Obj.IsStatement);
  IO.mapRequired("EndDelta", Obj.EndDelta);
}

void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) {
  IO.mapRequired("StartColumn", Obj.StartColumn);
  IO.mapRequired("EndColumn", Obj.EndColumn);
}

void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) {
  IO.mapRequired("FileName", Obj.FileName);
  IO.mapRequired("Lines", Obj.Lines);
  IO.mapRequired("Columns", Obj.Columns);
}

void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) {
  IO.mapRequired("LocalId", Obj.Local);
  IO.mapRequired("GlobalId", Obj.Global);
}

void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO,
                                                   YAMLCrossModuleImport &Obj) {
  IO.mapRequired("Module", Obj.ModuleName);
  IO.mapRequired("Imports", Obj.ImportIds);
}

void MappingTraits<SourceFileChecksumEntry>::mapping(
    IO &IO, SourceFileChecksumEntry &Obj) {
  IO.mapRequired("FileName", Obj.FileName);
  IO.mapRequired("Kind", Obj.Kind);
  IO.mapRequired("Checksum", Obj.ChecksumBytes);
}

void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
  IO.mapRequired("FileName", Obj.FileName);
  IO.mapRequired("LineNum", Obj.SourceLineNum);
  IO.mapRequired("Inlinee", Obj.Inlinee);
  IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
}

void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) {
  IO.mapRequired("CodeSize", Obj.CodeSize);
  IO.mapRequired("FrameFunc", Obj.FrameFunc);
  IO.mapRequired("LocalSize", Obj.LocalSize);
  IO.mapOptional("MaxStackSize", Obj.MaxStackSize);
  IO.mapOptional("ParamsSize", Obj.ParamsSize);
  IO.mapOptional("PrologSize", Obj.PrologSize);
  IO.mapOptional("RvaStart", Obj.RvaStart);
  IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize);
}

void YAMLChecksumsSubsection::map(IO &IO) {
  IO.mapTag("!FileChecksums", true);
  IO.mapRequired("Checksums", Checksums);
}

void YAMLLinesSubsection::map(IO &IO) {
  IO.mapTag("!Lines", true);
  IO.mapRequired("CodeSize", Lines.CodeSize);

  IO.mapRequired("Flags", Lines.Flags);
  IO.mapRequired("RelocOffset", Lines.RelocOffset);
  IO.mapRequired("RelocSegment", Lines.RelocSegment);
  IO.mapRequired("Blocks", Lines.Blocks);
}

void YAMLInlineeLinesSubsection::map(IO &IO) {
  IO.mapTag("!InlineeLines", true);
  IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles);
  IO.mapRequired("Sites", InlineeLines.Sites);
}

void YAMLCrossModuleExportsSubsection::map(IO &IO) {
  IO.mapTag("!CrossModuleExports", true);
  IO.mapOptional("Exports", Exports);
}

void YAMLCrossModuleImportsSubsection::map(IO &IO) {
  IO.mapTag("!CrossModuleImports", true);
  IO.mapOptional("Imports", Imports);
}

void YAMLSymbolsSubsection::map(IO &IO) {
  IO.mapTag("!Symbols", true);
  IO.mapRequired("Records", Symbols);
}

void YAMLStringTableSubsection::map(IO &IO) {
  IO.mapTag("!StringTable", true);
  IO.mapRequired("Strings", Strings);
}

void YAMLFrameDataSubsection::map(IO &IO) {
  IO.mapTag("!FrameData", true);
  IO.mapRequired("Frames", Frames);
}

void YAMLCoffSymbolRVASubsection::map(IO &IO) {
  IO.mapTag("!COFFSymbolRVAs", true);
  IO.mapRequired("RVAs", RVAs);
}

void MappingTraits<YAMLDebugSubsection>::mapping(
    IO &IO, YAMLDebugSubsection &Subsection) {
  if (!IO.outputting()) {
    if (IO.mapTag("!FileChecksums")) {
      auto SS = std::make_shared<YAMLChecksumsSubsection>();
      Subsection.Subsection = SS;
    } else if (IO.mapTag("!Lines")) {
      Subsection.Subsection = std::make_shared<YAMLLinesSubsection>();
    } else if (IO.mapTag("!InlineeLines")) {
      Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>();
    } else if (IO.mapTag("!CrossModuleExports")) {
      Subsection.Subsection =
          std::make_shared<YAMLCrossModuleExportsSubsection>();
    } else if (IO.mapTag("!CrossModuleImports")) {
      Subsection.Subsection =
          std::make_shared<YAMLCrossModuleImportsSubsection>();
    } else if (IO.mapTag("!Symbols")) {
      Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>();
    } else if (IO.mapTag("!StringTable")) {
      Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
    } else if (IO.mapTag("!FrameData")) {
      Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
    } else if (IO.mapTag("!COFFSymbolRVAs")) {
      Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
    } else {
      llvm_unreachable("Unexpected subsection tag!");
    }
  }
  Subsection.Subsection->map(IO);
}

std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  assert(SC.hasStrings());
  auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings());
  for (const auto &CS : Checksums) {
    Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
  }
  return Result;
}

std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  assert(SC.hasStrings() && SC.hasChecksums());
  auto Result =
      std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings());
  Result->setCodeSize(Lines.CodeSize);
  Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
  Result->setFlags(Lines.Flags);
  for (const auto &LC : Lines.Blocks) {
    Result->createBlock(LC.FileName);
    if (Result->hasColumnInfo()) {
      for (const auto &Item : zip(LC.Lines, LC.Columns)) {
        auto &L = std::get<0>(Item);
        auto &C = std::get<1>(Item);
        uint32_t LE = L.LineStart + L.EndDelta;
        Result->addLineAndColumnInfo(L.Offset,
                                     LineInfo(L.LineStart, LE, L.IsStatement),
                                     C.StartColumn, C.EndColumn);
      }
    } else {
      for (const auto &L : LC.Lines) {
        uint32_t LE = L.LineStart + L.EndDelta;
        Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement));
      }
    }
  }
  return Result;
}

std::shared_ptr<DebugSubsection>
YAMLInlineeLinesSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  assert(SC.hasChecksums());
  auto Result = std::make_shared<DebugInlineeLinesSubsection>(
      *SC.checksums(), InlineeLines.HasExtraFiles);

  for (const auto &Site : InlineeLines.Sites) {
    Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
                          Site.SourceLineNum);
    if (!InlineeLines.HasExtraFiles)
      continue;

    for (auto EF : Site.ExtraFiles) {
      Result->addExtraFile(EF);
    }
  }
  return Result;
}

std::shared_ptr<DebugSubsection>
YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  auto Result = std::make_shared<DebugCrossModuleExportsSubsection>();
  for (const auto &M : Exports)
    Result->addMapping(M.Local, M.Global);
  return Result;
}

std::shared_ptr<DebugSubsection>
YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  assert(SC.hasStrings());

  auto Result =
      std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings());
  for (const auto &M : Imports) {
    for (const auto Id : M.ImportIds)
      Result->addImport(M.ModuleName, Id);
  }
  return Result;
}

std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  auto Result = std::make_shared<DebugSymbolsSubsection>();
  for (const auto &Sym : Symbols)
    Result->addSymbol(
        Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
  return Result;
}

std::shared_ptr<DebugSubsection>
YAMLStringTableSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  auto Result = std::make_shared<DebugStringTableSubsection>();
  for (const auto &Str : this->Strings)
    Result->insert(Str);
  return Result;
}

std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  assert(SC.hasStrings());

  auto Result = std::make_shared<DebugFrameDataSubsection>(true);
  for (const auto &YF : Frames) {
    codeview::FrameData F;
    F.CodeSize = YF.CodeSize;
    F.Flags = YF.Flags;
    F.LocalSize = YF.LocalSize;
    F.MaxStackSize = YF.MaxStackSize;
    F.ParamsSize = YF.ParamsSize;
    F.PrologSize = YF.PrologSize;
    F.RvaStart = YF.RvaStart;
    F.SavedRegsSize = YF.SavedRegsSize;
    F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
    Result->addFrameData(F);
  }
  return Result;
}

std::shared_ptr<DebugSubsection>
YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
    BumpPtrAllocator &Allocator,
    const codeview::StringsAndChecksums &SC) const {
  auto Result = std::make_shared<DebugSymbolRVASubsection>();
  for (const auto &RVA : RVAs)
    Result->addRVA(RVA);
  return Result;
}

static Expected<SourceFileChecksumEntry>
convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
                   const FileChecksumEntry &CS) {
  auto ExpectedString = Strings.getString(CS.FileNameOffset);
  if (!ExpectedString)
    return ExpectedString.takeError();

  SourceFileChecksumEntry Result;
  Result.ChecksumBytes.Bytes = CS.Checksum;
  Result.Kind = CS.Kind;
  Result.FileName = *ExpectedString;
  return Result;
}

static Expected<StringRef>
getFileName(const DebugStringTableSubsectionRef &Strings,
            const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
  auto Iter = Checksums.getArray().at(FileID);
  if (Iter == Checksums.getArray().end())
    return make_error<CodeViewError>(cv_error_code::no_records);
  uint32_t Offset = Iter->FileNameOffset;
  return Strings.getString(Offset);
}

Expected<std::shared_ptr<YAMLChecksumsSubsection>>
YAMLChecksumsSubsection::fromCodeViewSubsection(
    const DebugStringTableSubsectionRef &Strings,
    const DebugChecksumsSubsectionRef &FC) {
  auto Result = std::make_shared<YAMLChecksumsSubsection>();

  for (const auto &CS : FC) {
    auto ConvertedCS = convertOneChecksum(Strings, CS);
    if (!ConvertedCS)
      return ConvertedCS.takeError();
    Result->Checksums.push_back(*ConvertedCS);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLLinesSubsection>>
YAMLLinesSubsection::fromCodeViewSubsection(
    const DebugStringTableSubsectionRef &Strings,
    const DebugChecksumsSubsectionRef &Checksums,
    const DebugLinesSubsectionRef &Lines) {
  auto Result = std::make_shared<YAMLLinesSubsection>();
  Result->Lines.CodeSize = Lines.header()->CodeSize;
  Result->Lines.RelocOffset = Lines.header()->RelocOffset;
  Result->Lines.RelocSegment = Lines.header()->RelocSegment;
  Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags));
  for (const auto &L : Lines) {
    SourceLineBlock Block;
    auto EF = getFileName(Strings, Checksums, L.NameIndex);
    if (!EF)
      return EF.takeError();
    Block.FileName = *EF;
    if (Lines.hasColumnInfo()) {
      for (const auto &C : L.Columns) {
        SourceColumnEntry SCE;
        SCE.EndColumn = C.EndColumn;
        SCE.StartColumn = C.StartColumn;
        Block.Columns.push_back(SCE);
      }
    }
    for (const auto &LN : L.LineNumbers) {
      SourceLineEntry SLE;
      LineInfo LI(LN.Flags);
      SLE.Offset = LN.Offset;
      SLE.LineStart = LI.getStartLine();
      SLE.EndDelta = LI.getLineDelta();
      SLE.IsStatement = LI.isStatement();
      Block.Lines.push_back(SLE);
    }
    Result->Lines.Blocks.push_back(Block);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
YAMLInlineeLinesSubsection::fromCodeViewSubsection(
    const DebugStringTableSubsectionRef &Strings,
    const DebugChecksumsSubsectionRef &Checksums,
    const DebugInlineeLinesSubsectionRef &Lines) {
  auto Result = std::make_shared<YAMLInlineeLinesSubsection>();

  Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles();
  for (const auto &IL : Lines) {
    InlineeSite Site;
    auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID);
    if (!ExpF)
      return ExpF.takeError();
    Site.FileName = *ExpF;
    Site.Inlinee = IL.Header->Inlinee.getIndex();
    Site.SourceLineNum = IL.Header->SourceLineNum;
    if (Lines.hasExtraFiles()) {
      for (const auto EF : IL.ExtraFiles) {
        auto ExpF2 = getFileName(Strings, Checksums, EF);
        if (!ExpF2)
          return ExpF2.takeError();
        Site.ExtraFiles.push_back(*ExpF2);
      }
    }
    Result->InlineeLines.Sites.push_back(Site);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(
    const DebugCrossModuleExportsSubsectionRef &Exports) {
  auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>();
  Result->Exports.assign(Exports.begin(), Exports.end());
  return Result;
}

Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
    const DebugStringTableSubsectionRef &Strings,
    const DebugCrossModuleImportsSubsectionRef &Imports) {
  auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>();
  for (const auto &CMI : Imports) {
    YAMLCrossModuleImport YCMI;
    auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset);
    if (!ExpectedStr)
      return ExpectedStr.takeError();
    YCMI.ModuleName = *ExpectedStr;
    YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end());
    Result->Imports.push_back(YCMI);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLSymbolsSubsection>>
YAMLSymbolsSubsection::fromCodeViewSubsection(
    const DebugSymbolsSubsectionRef &Symbols) {
  auto Result = std::make_shared<YAMLSymbolsSubsection>();
  for (const auto &Sym : Symbols) {
    auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
    if (!S)
      return joinErrors(make_error<CodeViewError>(
                            cv_error_code::corrupt_record,
                            "Invalid CodeView Symbol Record in SymbolRecord "
                            "subsection of .debug$S while converting to YAML!"),
                        S.takeError());

    Result->Symbols.push_back(*S);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLStringTableSubsection>>
YAMLStringTableSubsection::fromCodeViewSubsection(
    const DebugStringTableSubsectionRef &Strings) {
  auto Result = std::make_shared<YAMLStringTableSubsection>();
  BinaryStreamReader Reader(Strings.getBuffer());
  StringRef S;
  // First item is a single null string, skip it.
  if (auto EC = Reader.readCString(S))
    return std::move(EC);
  assert(S.empty());
  while (Reader.bytesRemaining() > 0) {
    if (auto EC = Reader.readCString(S))
      return std::move(EC);
    Result->Strings.push_back(S);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLFrameDataSubsection>>
YAMLFrameDataSubsection::fromCodeViewSubsection(
    const DebugStringTableSubsectionRef &Strings,
    const DebugFrameDataSubsectionRef &Frames) {
  auto Result = std::make_shared<YAMLFrameDataSubsection>();
  for (const auto &F : Frames) {
    YAMLFrameData YF;
    YF.CodeSize = F.CodeSize;
    YF.Flags = F.Flags;
    YF.LocalSize = F.LocalSize;
    YF.MaxStackSize = F.MaxStackSize;
    YF.ParamsSize = F.ParamsSize;
    YF.PrologSize = F.PrologSize;
    YF.RvaStart = F.RvaStart;
    YF.SavedRegsSize = F.SavedRegsSize;

    auto ES = Strings.getString(F.FrameFunc);
    if (!ES)
      return joinErrors(
          make_error<CodeViewError>(
              cv_error_code::no_records,
              "Could not find string for string id while mapping FrameData!"),
          ES.takeError());
    YF.FrameFunc = *ES;
    Result->Frames.push_back(YF);
  }
  return Result;
}

Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
    const DebugSymbolRVASubsectionRef &Section) {
  auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
  for (const auto &RVA : Section) {
    Result->RVAs.push_back(RVA);
  }
  return Result;
}

Expected<std::vector<std::shared_ptr<DebugSubsection>>>
llvm::CodeViewYAML::toCodeViewSubsectionList(
    BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
    const codeview::StringsAndChecksums &SC) {
  std::vector<std::shared_ptr<DebugSubsection>> Result;
  if (Subsections.empty())
    return std::move(Result);

  for (const auto &SS : Subsections) {
    std::shared_ptr<DebugSubsection> CVS;
    CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
    assert(CVS != nullptr);
    Result.push_back(std::move(CVS));
  }
  return std::move(Result);
}

namespace {

struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
  SubsectionConversionVisitor() = default;

  Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
  Error visitLines(DebugLinesSubsectionRef &Lines,
                   const StringsAndChecksumsRef &State) override;
  Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
                           const StringsAndChecksumsRef &State) override;
  Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
                          const StringsAndChecksumsRef &State) override;
  Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
                                const StringsAndChecksumsRef &State) override;
  Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
                                const StringsAndChecksumsRef &State) override;
  Error visitStringTable(DebugStringTableSubsectionRef &ST,
                         const StringsAndChecksumsRef &State) override;
  Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
                     const StringsAndChecksumsRef &State) override;
  Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
                       const StringsAndChecksumsRef &State) override;
  Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
                            const StringsAndChecksumsRef &State) override;

  YAMLDebugSubsection Subsection;
};

} // end anonymous namespace

Error SubsectionConversionVisitor::visitUnknown(
    DebugUnknownSubsectionRef &Unknown) {
  return make_error<CodeViewError>(cv_error_code::operation_unsupported);
}

Error SubsectionConversionVisitor::visitLines(
    DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
  auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
      State.strings(), State.checksums(), Lines);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitFileChecksums(
    DebugChecksumsSubsectionRef &Checksums,
    const StringsAndChecksumsRef &State) {
  auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
                                                                Checksums);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitInlineeLines(
    DebugInlineeLinesSubsectionRef &Inlinees,
    const StringsAndChecksumsRef &State) {
  auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
      State.strings(), State.checksums(), Inlinees);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitCrossModuleExports(
    DebugCrossModuleExportsSubsectionRef &Exports,
    const StringsAndChecksumsRef &State) {
  auto Result =
      YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitCrossModuleImports(
    DebugCrossModuleImportsSubsectionRef &Imports,
    const StringsAndChecksumsRef &State) {
  auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
      State.strings(), Imports);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitStringTable(
    DebugStringTableSubsectionRef &Strings,
    const StringsAndChecksumsRef &State) {
  auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitSymbols(
    DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
  auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitFrameData(
    DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
  auto Result =
      YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
    DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
  auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
  if (!Result)
    return Result.takeError();
  Subsection.Subsection = *Result;
  return Error::success();
}

Expected<YAMLDebugSubsection>
YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
                                           const DebugSubsectionRecord &SS) {
  SubsectionConversionVisitor V;
  if (auto EC = visitDebugSubsection(SS, V, SC))
    return std::move(EC);

  return V.Subsection;
}

std::vector<YAMLDebugSubsection>
llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data,
                               const StringsAndChecksumsRef &SC) {
  BinaryStreamReader Reader(Data, support::little);
  uint32_t Magic;

  ExitOnError Err("Invalid .debug$S section!");
  Err(Reader.readInteger(Magic));
  assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");

  DebugSubsectionArray Subsections;
  Err(Reader.readArray(Subsections, Reader.bytesRemaining()));

  std::vector<YAMLDebugSubsection> Result;

  for (const auto &SS : Subsections) {
    auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
    Result.push_back(YamlSS);
  }
  return Result;
}

void llvm::CodeViewYAML::initializeStringsAndChecksums(
    ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) {
  // String Table and Checksums subsections don't use the allocator.
  BumpPtrAllocator Allocator;

  // It's possible for checksums and strings to even appear in different debug$S
  // sections, so we have to make this a stateful function that can build up
  // the strings and checksums field over multiple iterations.

  // File Checksums require the string table, but may become before it, so we
  // have to scan for strings first, then scan for checksums again from the
  // beginning.
  if (!SC.hasStrings()) {
    for (const auto &SS : Sections) {
      if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
        continue;

      auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
      SC.setStrings(
          std::static_pointer_cast<DebugStringTableSubsection>(Result));
      break;
    }
  }

  if (SC.hasStrings() && !SC.hasChecksums()) {
    for (const auto &SS : Sections) {
      if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
        continue;

      auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
      SC.setChecksums(
          std::static_pointer_cast<DebugChecksumsSubsection>(Result));
      break;
    }
  }
}
