//===- 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 <cassert>
#include <cstdint>
#include <memory>
#include <string>
#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 (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>();
  llvm::append_range(Result->RVAs, Section);
  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, llvm::endianness::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;
    }
  }
}
