//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
//
// 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/CodeViewYAMLSymbols.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstdint>
#include <cstring>
#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_FLOW_SEQUENCE_VECTOR(TypeIndex)
LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)

// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)

LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)

LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)

LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)

LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)

StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
  return ScalarTraits<StringRef>::input(S, V, T.value);
}

void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
                                    raw_ostream &R) {
  ScalarTraits<StringRef>::output(T.value, V, R);
}

void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
                                                      SymbolKind &Value) {
  auto SymbolNames = getSymbolTypeNames();
  for (const auto &E : SymbolNames)
    io.enumCase(Value, E.Name.str().c_str(), E.Value);
}

void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
                                                  CompileSym2Flags &Flags) {
  auto FlagNames = getCompileSym2FlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<CompileSym2Flags>(E.Value));
  }
}

void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
                                                  CompileSym3Flags &Flags) {
  auto FlagNames = getCompileSym3FlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<CompileSym3Flags>(E.Value));
  }
}

void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
  auto FlagNames = getExportSymFlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<ExportFlags>(E.Value));
  }
}

void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
  auto FlagNames = getPublicSymFlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<PublicSymFlags>(E.Value));
  }
}

void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
  auto FlagNames = getLocalFlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<LocalSymFlags>(E.Value));
  }
}

void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
  auto FlagNames = getProcSymFlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<ProcSymFlags>(E.Value));
  }
}

void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
    IO &io, FrameProcedureOptions &Flags) {
  auto FlagNames = getFrameProcSymFlagNames();
  for (const auto &E : FlagNames) {
    io.bitSetCase(Flags, E.Name.str().c_str(),
                  static_cast<FrameProcedureOptions>(E.Value));
  }
}

void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
  auto CpuNames = getCPUTypeNames();
  for (const auto &E : CpuNames) {
    io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
  }
}

void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
  const auto *Header = static_cast<COFF::header *>(io.getContext());
  assert(Header && "The IO context is not initialized");

  Optional<CPUType> CpuType;
  ArrayRef<EnumEntry<uint16_t>> RegNames;

  switch (Header->Machine) {
  case COFF::IMAGE_FILE_MACHINE_I386:
    CpuType = CPUType::Pentium3;
    break;
  case COFF::IMAGE_FILE_MACHINE_AMD64:
    CpuType = CPUType::X64;
    break;
  case COFF::IMAGE_FILE_MACHINE_ARMNT:
    CpuType = CPUType::ARMNT;
    break;
  case COFF::IMAGE_FILE_MACHINE_ARM64:
    CpuType = CPUType::ARM64;
    break;
  }

  if (CpuType)
    RegNames = getRegisterNames(*CpuType);

  for (const auto &E : RegNames) {
    io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
  }
  io.enumFallback<Hex16>(Reg);
}

void ScalarEnumerationTraits<TrampolineType>::enumeration(
    IO &io, TrampolineType &Tramp) {
  auto TrampNames = getTrampolineNames();
  for (const auto &E : TrampNames) {
    io.enumCase(Tramp, E.Name.str().c_str(),
                static_cast<TrampolineType>(E.Value));
  }
}

void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
                                                        ThunkOrdinal &Ord) {
  auto ThunkNames = getThunkOrdinalNames();
  for (const auto &E : ThunkNames) {
    io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
  }
}

void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
    IO &io, FrameCookieKind &FC) {
  auto ThunkNames = getFrameCookieKindNames();
  for (const auto &E : ThunkNames) {
    io.enumCase(FC, E.Name.str().c_str(),
                static_cast<FrameCookieKind>(E.Value));
  }
}

namespace llvm {
namespace yaml {
template <> struct MappingTraits<LocalVariableAddrRange> {
  static void mapping(IO &io, LocalVariableAddrRange &Range) {
    io.mapRequired("OffsetStart", Range.OffsetStart);
    io.mapRequired("ISectStart", Range.ISectStart);
    io.mapRequired("Range", Range.Range);
  }
};
template <> struct MappingTraits<LocalVariableAddrGap> {
  static void mapping(IO &io, LocalVariableAddrGap &Gap) {
    io.mapRequired("GapStartOffset", Gap.GapStartOffset);
    io.mapRequired("Range", Gap.Range);
  }
};
} // namespace yaml
} // namespace llvm

namespace llvm {
namespace CodeViewYAML {
namespace detail {

struct SymbolRecordBase {
  codeview::SymbolKind Kind;

  explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
  virtual ~SymbolRecordBase() = default;

  virtual void map(yaml::IO &io) = 0;
  virtual codeview::CVSymbol
  toCodeViewSymbol(BumpPtrAllocator &Allocator,
                   CodeViewContainer Container) const = 0;
  virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
};

template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
  explicit SymbolRecordImpl(codeview::SymbolKind K)
      : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}

  void map(yaml::IO &io) override;

  codeview::CVSymbol
  toCodeViewSymbol(BumpPtrAllocator &Allocator,
                   CodeViewContainer Container) const override {
    return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
  }

  Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
    return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
  }

  mutable T Symbol;
};

struct UnknownSymbolRecord : public SymbolRecordBase {
  explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}

  void map(yaml::IO &io) override;

  CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
                            CodeViewContainer Container) const override {
    RecordPrefix Prefix;
    uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
    Prefix.RecordKind = Kind;
    Prefix.RecordLen = TotalLen - 2;
    uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
    ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
    ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
    return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
  }

  Error fromCodeViewSymbol(CVSymbol CVS) override {
    this->Kind = CVS.kind();
    Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
    return Error::success();
  }

  std::vector<uint8_t> Data;
};

template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}

void UnknownSymbolRecord::map(yaml::IO &io) {
  yaml::BinaryRef Binary;
  if (io.outputting())
    Binary = yaml::BinaryRef(Data);
  io.mapRequired("Data", Binary);
  if (!io.outputting()) {
    std::string Str;
    raw_string_ostream OS(Str);
    Binary.writeAsBinary(OS);
    OS.flush();
    Data.assign(Str.begin(), Str.end());
  }
}

template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
  IO.mapRequired("Parent", Symbol.Parent);
  IO.mapRequired("End", Symbol.End);
  IO.mapRequired("Next", Symbol.Next);
  IO.mapRequired("Off", Symbol.Offset);
  IO.mapRequired("Seg", Symbol.Segment);
  IO.mapRequired("Len", Symbol.Length);
  IO.mapRequired("Ordinal", Symbol.Thunk);
}

template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Type);
  IO.mapRequired("Size", Symbol.Size);
  IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
  IO.mapRequired("TargetOff", Symbol.TargetOffset);
  IO.mapRequired("ThunkSection", Symbol.ThunkSection);
  IO.mapRequired("TargetSection", Symbol.TargetSection);
}

template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
  IO.mapRequired("SectionNumber", Symbol.SectionNumber);
  IO.mapRequired("Alignment", Symbol.Alignment);
  IO.mapRequired("Rva", Symbol.Rva);
  IO.mapRequired("Length", Symbol.Length);
  IO.mapRequired("Characteristics", Symbol.Characteristics);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
  IO.mapRequired("Size", Symbol.Size);
  IO.mapRequired("Characteristics", Symbol.Characteristics);
  IO.mapRequired("Offset", Symbol.Offset);
  IO.mapRequired("Segment", Symbol.Segment);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
  IO.mapRequired("Ordinal", Symbol.Ordinal);
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
  IO.mapOptional("PtrEnd", Symbol.End, 0U);
  IO.mapOptional("PtrNext", Symbol.Next, 0U);
  IO.mapRequired("CodeSize", Symbol.CodeSize);
  IO.mapRequired("DbgStart", Symbol.DbgStart);
  IO.mapRequired("DbgEnd", Symbol.DbgEnd);
  IO.mapRequired("FunctionType", Symbol.FunctionType);
  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("DisplayName", Symbol.Name);
}

template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Index);
  IO.mapRequired("Seg", Symbol.Register);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapOptional("Offset", Symbol.Offset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
  IO.mapRequired("SumName", Symbol.SumName);
  IO.mapRequired("SymOffset", Symbol.SymOffset);
  IO.mapRequired("Mod", Symbol.Module);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
  IO.mapRequired("Entries", Symbol.Fields);
}

template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
  IO.mapOptional("PtrEnd", Symbol.End, 0U);
  IO.mapRequired("Inlinee", Symbol.Inlinee);
  // TODO: The binary annotations
}

template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Type);
  IO.mapRequired("Flags", Symbol.Flags);

  IO.mapRequired("VarName", Symbol.Name);
}

template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
  IO.mapRequired("Program", Symbol.Program);
  IO.mapRequired("Range", Symbol.Range);
  IO.mapRequired("Gaps", Symbol.Gaps);
}

template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
  IO.mapRequired("Program", Symbol.Program);
  IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
  IO.mapRequired("Range", Symbol.Range);
  IO.mapRequired("Gaps", Symbol.Gaps);
}

template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
  IO.mapRequired("Register", Symbol.Hdr.Register);
  IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
  IO.mapRequired("Range", Symbol.Range);
  IO.mapRequired("Gaps", Symbol.Gaps);
}

template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
  IO.mapRequired("Offset", Symbol.Hdr.Offset);
  IO.mapRequired("Range", Symbol.Range);
  IO.mapRequired("Gaps", Symbol.Gaps);
}

template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
  IO.mapRequired("Register", Symbol.Hdr.Register);
  IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
  IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
  IO.mapRequired("Range", Symbol.Range);
  IO.mapRequired("Gaps", Symbol.Gaps);
}

template <>
void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
  IO.mapRequired("Register", Symbol.Offset);
}

template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
  IO.mapRequired("Register", Symbol.Hdr.Register);
  IO.mapRequired("Flags", Symbol.Hdr.Flags);
  IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
  IO.mapRequired("Range", Symbol.Range);
  IO.mapRequired("Gaps", Symbol.Gaps);
}

template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
  IO.mapOptional("PtrEnd", Symbol.End, 0U);
  IO.mapRequired("CodeSize", Symbol.CodeSize);
  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("BlockName", Symbol.Name);
}

template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("DisplayName", Symbol.Name);
}

template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
  IO.mapRequired("Signature", Symbol.Signature);
  IO.mapRequired("ObjectName", Symbol.Name);
}

template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("Machine", Symbol.Machine);
  IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
  IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
  IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
  IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
  IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
  IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
  IO.mapRequired("Version", Symbol.Version);
}

template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("Machine", Symbol.Machine);
  IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
  IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
  IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
  IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
  IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
  IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
  IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
  IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
  IO.mapRequired("Version", Symbol.Version);
}

template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
  IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
  IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
  IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
  IO.mapRequired("BytesOfCalleeSavedRegisters",
                 Symbol.BytesOfCalleeSavedRegisters);
  IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
  IO.mapRequired("SectionIdOfExceptionHandler",
                 Symbol.SectionIdOfExceptionHandler);
  IO.mapRequired("Flags", Symbol.Flags);
}

template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("Type", Symbol.Type);
}

template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
  IO.mapRequired("Index", Symbol.Index);
  IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
  IO.mapRequired("Flags", Symbol.Flags);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
  IO.mapRequired("Type", Symbol.Type);
}

template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
  IO.mapRequired("Register", Symbol.Register);
  IO.mapRequired("CookieKind", Symbol.CookieKind);
  IO.mapRequired("Flags", Symbol.Flags);
}

template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
  IO.mapRequired("FuncID", Symbol.Indices);
}

template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Type);
  IO.mapRequired("UDTName", Symbol.Name);
}

template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
  IO.mapRequired("BuildId", Symbol.BuildId);
}

template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
  IO.mapRequired("Offset", Symbol.Offset);
  IO.mapRequired("Type", Symbol.Type);
  IO.mapRequired("VarName", Symbol.Name);
}

template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
  IO.mapRequired("Offset", Symbol.Offset);
  IO.mapRequired("Type", Symbol.Type);
  IO.mapRequired("Register", Symbol.Register);
  IO.mapRequired("VarName", Symbol.Name);
}

template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Type);
  IO.mapRequired("Value", Symbol.Value);
  IO.mapRequired("Name", Symbol.Name);
}

template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Type);
  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("DisplayName", Symbol.Name);
}

template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
  IO.mapRequired("Type", Symbol.Type);
  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("DisplayName", Symbol.Name);
}

template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
  IO.mapRequired("Namespace", Symbol.Name);
}

template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  IO.mapRequired("Strings", Symbol.Strings);
}

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

CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
    BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
  return Symbol->toCodeViewSymbol(Allocator, Container);
}

namespace llvm {
namespace yaml {

template <> struct MappingTraits<SymbolRecordBase> {
  static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
};

} // end namespace yaml
} // end namespace llvm

template <typename SymbolType>
static inline Expected<CodeViewYAML::SymbolRecord>
fromCodeViewSymbolImpl(CVSymbol Symbol) {
  CodeViewYAML::SymbolRecord Result;

  auto Impl = std::make_shared<SymbolType>(Symbol.kind());
  if (auto EC = Impl->fromCodeViewSymbol(Symbol))
    return std::move(EC);
  Result.Symbol = Impl;
  return Result;
}

Expected<CodeViewYAML::SymbolRecord>
CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
#define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
  case EnumName:                                                               \
    return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
  SYMBOL_RECORD(EnumName, EnumVal, ClassName)
  switch (Symbol.kind()) {
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  default:
    return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
  }
  return make_error<CodeViewError>(cv_error_code::corrupt_record);
}

template <typename ConcreteType>
static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
                                CodeViewYAML::SymbolRecord &Obj) {
  if (!IO.outputting())
    Obj.Symbol = std::make_shared<ConcreteType>(Kind);

  IO.mapRequired(Class, *Obj.Symbol);
}

void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
    IO &IO, CodeViewYAML::SymbolRecord &Obj) {
  SymbolKind Kind;
  if (IO.outputting())
    Kind = Obj.Symbol->Kind;
  IO.mapRequired("Kind", Kind);

#define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
  case EnumName:                                                               \
    mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
                                                     Obj);                     \
    break;
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
  SYMBOL_RECORD(EnumName, EnumVal, ClassName)
  switch (Kind) {
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  default:
    mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
  }
}
