xref: /freebsd-src/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines classes for handling the YAML representation of CodeView
100b57cec5SDimitry Andric // Debug Info.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
170b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
180b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
190b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/EnumTables.h"
200b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
210b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
220b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
230b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
240b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
250b57cec5SDimitry Andric #include "llvm/ObjectYAML/YAML.h"
260b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
270b57cec5SDimitry Andric #include "llvm/Support/Error.h"
2881ad6265SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
290b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h"
300b57cec5SDimitry Andric #include <algorithm>
310b57cec5SDimitry Andric #include <cstdint>
320b57cec5SDimitry Andric #include <cstring>
33bdd1243dSDimitry Andric #include <optional>
340b57cec5SDimitry Andric #include <string>
350b57cec5SDimitry Andric #include <vector>
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric using namespace llvm;
380b57cec5SDimitry Andric using namespace llvm::codeview;
390b57cec5SDimitry Andric using namespace llvm::CodeViewYAML;
400b57cec5SDimitry Andric using namespace llvm::CodeViewYAML::detail;
410b57cec5SDimitry Andric using namespace llvm::yaml;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
440b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
470b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
480b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
510b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
540b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
550b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
560b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
570b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
580b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
590b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
600b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
610b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
620b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
630b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
64*5f757f3fSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(JumpTableEntrySize)
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
710b57cec5SDimitry Andric   return ScalarTraits<StringRef>::input(S, V, T.value);
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
750b57cec5SDimitry Andric                                     raw_ostream &R) {
760b57cec5SDimitry Andric   ScalarTraits<StringRef>::output(T.value, V, R);
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
800b57cec5SDimitry Andric                                                       SymbolKind &Value) {
810b57cec5SDimitry Andric   auto SymbolNames = getSymbolTypeNames();
820b57cec5SDimitry Andric   for (const auto &E : SymbolNames)
830b57cec5SDimitry Andric     io.enumCase(Value, E.Name.str().c_str(), E.Value);
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
870b57cec5SDimitry Andric                                                   CompileSym2Flags &Flags) {
880b57cec5SDimitry Andric   auto FlagNames = getCompileSym2FlagNames();
890b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
900b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
910b57cec5SDimitry Andric                   static_cast<CompileSym2Flags>(E.Value));
920b57cec5SDimitry Andric   }
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
960b57cec5SDimitry Andric                                                   CompileSym3Flags &Flags) {
970b57cec5SDimitry Andric   auto FlagNames = getCompileSym3FlagNames();
980b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
990b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
1000b57cec5SDimitry Andric                   static_cast<CompileSym3Flags>(E.Value));
1010b57cec5SDimitry Andric   }
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
1050b57cec5SDimitry Andric   auto FlagNames = getExportSymFlagNames();
1060b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
1070b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
1080b57cec5SDimitry Andric                   static_cast<ExportFlags>(E.Value));
1090b57cec5SDimitry Andric   }
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
1130b57cec5SDimitry Andric   auto FlagNames = getPublicSymFlagNames();
1140b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
1150b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
1160b57cec5SDimitry Andric                   static_cast<PublicSymFlags>(E.Value));
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
1210b57cec5SDimitry Andric   auto FlagNames = getLocalFlagNames();
1220b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
1230b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
1240b57cec5SDimitry Andric                   static_cast<LocalSymFlags>(E.Value));
1250b57cec5SDimitry Andric   }
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
1290b57cec5SDimitry Andric   auto FlagNames = getProcSymFlagNames();
1300b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
1310b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
1320b57cec5SDimitry Andric                   static_cast<ProcSymFlags>(E.Value));
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
1370b57cec5SDimitry Andric     IO &io, FrameProcedureOptions &Flags) {
1380b57cec5SDimitry Andric   auto FlagNames = getFrameProcSymFlagNames();
1390b57cec5SDimitry Andric   for (const auto &E : FlagNames) {
1400b57cec5SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
1410b57cec5SDimitry Andric                   static_cast<FrameProcedureOptions>(E.Value));
1420b57cec5SDimitry Andric   }
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
1460b57cec5SDimitry Andric   auto CpuNames = getCPUTypeNames();
1470b57cec5SDimitry Andric   for (const auto &E : CpuNames) {
1480b57cec5SDimitry Andric     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
153e8d8bef9SDimitry Andric   const auto *Header = static_cast<COFF::header *>(io.getContext());
154e8d8bef9SDimitry Andric   assert(Header && "The IO context is not initialized");
155e8d8bef9SDimitry Andric 
156bdd1243dSDimitry Andric   std::optional<CPUType> CpuType;
157e8d8bef9SDimitry Andric   ArrayRef<EnumEntry<uint16_t>> RegNames;
158e8d8bef9SDimitry Andric 
159e8d8bef9SDimitry Andric   switch (Header->Machine) {
160e8d8bef9SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_I386:
161e8d8bef9SDimitry Andric     CpuType = CPUType::Pentium3;
162e8d8bef9SDimitry Andric     break;
163e8d8bef9SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_AMD64:
164e8d8bef9SDimitry Andric     CpuType = CPUType::X64;
165e8d8bef9SDimitry Andric     break;
166e8d8bef9SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARMNT:
167e8d8bef9SDimitry Andric     CpuType = CPUType::ARMNT;
168e8d8bef9SDimitry Andric     break;
169e8d8bef9SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARM64:
170bdd1243dSDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
17106c3fb27SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARM64X:
172e8d8bef9SDimitry Andric     CpuType = CPUType::ARM64;
173e8d8bef9SDimitry Andric     break;
174e8d8bef9SDimitry Andric   }
175e8d8bef9SDimitry Andric 
176e8d8bef9SDimitry Andric   if (CpuType)
177e8d8bef9SDimitry Andric     RegNames = getRegisterNames(*CpuType);
178e8d8bef9SDimitry Andric 
1790b57cec5SDimitry Andric   for (const auto &E : RegNames) {
1800b57cec5SDimitry Andric     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
1810b57cec5SDimitry Andric   }
1820b57cec5SDimitry Andric   io.enumFallback<Hex16>(Reg);
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric void ScalarEnumerationTraits<TrampolineType>::enumeration(
1860b57cec5SDimitry Andric     IO &io, TrampolineType &Tramp) {
1870b57cec5SDimitry Andric   auto TrampNames = getTrampolineNames();
1880b57cec5SDimitry Andric   for (const auto &E : TrampNames) {
1890b57cec5SDimitry Andric     io.enumCase(Tramp, E.Name.str().c_str(),
1900b57cec5SDimitry Andric                 static_cast<TrampolineType>(E.Value));
1910b57cec5SDimitry Andric   }
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
1950b57cec5SDimitry Andric                                                         ThunkOrdinal &Ord) {
1960b57cec5SDimitry Andric   auto ThunkNames = getThunkOrdinalNames();
1970b57cec5SDimitry Andric   for (const auto &E : ThunkNames) {
1980b57cec5SDimitry Andric     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
1990b57cec5SDimitry Andric   }
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
2030b57cec5SDimitry Andric     IO &io, FrameCookieKind &FC) {
2040b57cec5SDimitry Andric   auto ThunkNames = getFrameCookieKindNames();
2050b57cec5SDimitry Andric   for (const auto &E : ThunkNames) {
2060b57cec5SDimitry Andric     io.enumCase(FC, E.Name.str().c_str(),
2070b57cec5SDimitry Andric                 static_cast<FrameCookieKind>(E.Value));
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric 
211*5f757f3fSDimitry Andric void ScalarEnumerationTraits<JumpTableEntrySize>::enumeration(
212*5f757f3fSDimitry Andric     IO &io, JumpTableEntrySize &FC) {
213*5f757f3fSDimitry Andric   auto ThunkNames = getJumpTableEntrySizeNames();
214*5f757f3fSDimitry Andric   for (const auto &E : ThunkNames) {
215*5f757f3fSDimitry Andric     io.enumCase(FC, E.Name.str().c_str(),
216*5f757f3fSDimitry Andric                 static_cast<JumpTableEntrySize>(E.Value));
217*5f757f3fSDimitry Andric   }
218*5f757f3fSDimitry Andric }
219*5f757f3fSDimitry Andric 
2200b57cec5SDimitry Andric namespace llvm {
2210b57cec5SDimitry Andric namespace yaml {
2220b57cec5SDimitry Andric template <> struct MappingTraits<LocalVariableAddrRange> {
2230b57cec5SDimitry Andric   static void mapping(IO &io, LocalVariableAddrRange &Range) {
2240b57cec5SDimitry Andric     io.mapRequired("OffsetStart", Range.OffsetStart);
2250b57cec5SDimitry Andric     io.mapRequired("ISectStart", Range.ISectStart);
2260b57cec5SDimitry Andric     io.mapRequired("Range", Range.Range);
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric };
2290b57cec5SDimitry Andric template <> struct MappingTraits<LocalVariableAddrGap> {
2300b57cec5SDimitry Andric   static void mapping(IO &io, LocalVariableAddrGap &Gap) {
2310b57cec5SDimitry Andric     io.mapRequired("GapStartOffset", Gap.GapStartOffset);
2320b57cec5SDimitry Andric     io.mapRequired("Range", Gap.Range);
2330b57cec5SDimitry Andric   }
2340b57cec5SDimitry Andric };
2350b57cec5SDimitry Andric } // namespace yaml
2360b57cec5SDimitry Andric } // namespace llvm
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric namespace llvm {
2390b57cec5SDimitry Andric namespace CodeViewYAML {
2400b57cec5SDimitry Andric namespace detail {
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric struct SymbolRecordBase {
2430b57cec5SDimitry Andric   codeview::SymbolKind Kind;
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
2460b57cec5SDimitry Andric   virtual ~SymbolRecordBase() = default;
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   virtual void map(yaml::IO &io) = 0;
2490b57cec5SDimitry Andric   virtual codeview::CVSymbol
2500b57cec5SDimitry Andric   toCodeViewSymbol(BumpPtrAllocator &Allocator,
2510b57cec5SDimitry Andric                    CodeViewContainer Container) const = 0;
2520b57cec5SDimitry Andric   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
2530b57cec5SDimitry Andric };
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
2560b57cec5SDimitry Andric   explicit SymbolRecordImpl(codeview::SymbolKind K)
2570b57cec5SDimitry Andric       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   void map(yaml::IO &io) override;
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   codeview::CVSymbol
2620b57cec5SDimitry Andric   toCodeViewSymbol(BumpPtrAllocator &Allocator,
2630b57cec5SDimitry Andric                    CodeViewContainer Container) const override {
2640b57cec5SDimitry Andric     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
2680b57cec5SDimitry Andric     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
2690b57cec5SDimitry Andric   }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric   mutable T Symbol;
2720b57cec5SDimitry Andric };
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric struct UnknownSymbolRecord : public SymbolRecordBase {
2750b57cec5SDimitry Andric   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   void map(yaml::IO &io) override;
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
2800b57cec5SDimitry Andric                             CodeViewContainer Container) const override {
2810b57cec5SDimitry Andric     RecordPrefix Prefix;
2820b57cec5SDimitry Andric     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
2830b57cec5SDimitry Andric     Prefix.RecordKind = Kind;
2840b57cec5SDimitry Andric     Prefix.RecordLen = TotalLen - 2;
2850b57cec5SDimitry Andric     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
2860b57cec5SDimitry Andric     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
2870b57cec5SDimitry Andric     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
2880b57cec5SDimitry Andric     return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   Error fromCodeViewSymbol(CVSymbol CVS) override {
2920b57cec5SDimitry Andric     this->Kind = CVS.kind();
2930b57cec5SDimitry Andric     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
2940b57cec5SDimitry Andric     return Error::success();
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   std::vector<uint8_t> Data;
2980b57cec5SDimitry Andric };
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric void UnknownSymbolRecord::map(yaml::IO &io) {
3030b57cec5SDimitry Andric   yaml::BinaryRef Binary;
3040b57cec5SDimitry Andric   if (io.outputting())
3050b57cec5SDimitry Andric     Binary = yaml::BinaryRef(Data);
3060b57cec5SDimitry Andric   io.mapRequired("Data", Binary);
3070b57cec5SDimitry Andric   if (!io.outputting()) {
3080b57cec5SDimitry Andric     std::string Str;
3090b57cec5SDimitry Andric     raw_string_ostream OS(Str);
3100b57cec5SDimitry Andric     Binary.writeAsBinary(OS);
3110b57cec5SDimitry Andric     OS.flush();
3120b57cec5SDimitry Andric     Data.assign(Str.begin(), Str.end());
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
3170b57cec5SDimitry Andric   IO.mapRequired("Parent", Symbol.Parent);
3180b57cec5SDimitry Andric   IO.mapRequired("End", Symbol.End);
3190b57cec5SDimitry Andric   IO.mapRequired("Next", Symbol.Next);
3200b57cec5SDimitry Andric   IO.mapRequired("Off", Symbol.Offset);
3210b57cec5SDimitry Andric   IO.mapRequired("Seg", Symbol.Segment);
3220b57cec5SDimitry Andric   IO.mapRequired("Len", Symbol.Length);
3230b57cec5SDimitry Andric   IO.mapRequired("Ordinal", Symbol.Thunk);
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
3270b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
3280b57cec5SDimitry Andric   IO.mapRequired("Size", Symbol.Size);
3290b57cec5SDimitry Andric   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
3300b57cec5SDimitry Andric   IO.mapRequired("TargetOff", Symbol.TargetOffset);
3310b57cec5SDimitry Andric   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
3320b57cec5SDimitry Andric   IO.mapRequired("TargetSection", Symbol.TargetSection);
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
3360b57cec5SDimitry Andric   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
3370b57cec5SDimitry Andric   IO.mapRequired("Alignment", Symbol.Alignment);
3380b57cec5SDimitry Andric   IO.mapRequired("Rva", Symbol.Rva);
3390b57cec5SDimitry Andric   IO.mapRequired("Length", Symbol.Length);
3400b57cec5SDimitry Andric   IO.mapRequired("Characteristics", Symbol.Characteristics);
3410b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
3450b57cec5SDimitry Andric   IO.mapRequired("Size", Symbol.Size);
3460b57cec5SDimitry Andric   IO.mapRequired("Characteristics", Symbol.Characteristics);
3470b57cec5SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
3480b57cec5SDimitry Andric   IO.mapRequired("Segment", Symbol.Segment);
3490b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
3530b57cec5SDimitry Andric   IO.mapRequired("Ordinal", Symbol.Ordinal);
3540b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
3550b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
3590b57cec5SDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
3600b57cec5SDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
3610b57cec5SDimitry Andric   IO.mapOptional("PtrNext", Symbol.Next, 0U);
3620b57cec5SDimitry Andric   IO.mapRequired("CodeSize", Symbol.CodeSize);
3630b57cec5SDimitry Andric   IO.mapRequired("DbgStart", Symbol.DbgStart);
3640b57cec5SDimitry Andric   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
3650b57cec5SDimitry Andric   IO.mapRequired("FunctionType", Symbol.FunctionType);
3660b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
3670b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
3680b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
3690b57cec5SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
3730b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Index);
3740b57cec5SDimitry Andric   IO.mapRequired("Seg", Symbol.Register);
3750b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
3790b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
3800b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.Offset, 0U);
3810b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
3820b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
3860b57cec5SDimitry Andric   IO.mapRequired("SumName", Symbol.SumName);
3870b57cec5SDimitry Andric   IO.mapRequired("SymOffset", Symbol.SymOffset);
3880b57cec5SDimitry Andric   IO.mapRequired("Mod", Symbol.Module);
3890b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
3930b57cec5SDimitry Andric   IO.mapRequired("Entries", Symbol.Fields);
3940b57cec5SDimitry Andric }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
3970b57cec5SDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
3980b57cec5SDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
3990b57cec5SDimitry Andric   IO.mapRequired("Inlinee", Symbol.Inlinee);
4000b57cec5SDimitry Andric   // TODO: The binary annotations
4010b57cec5SDimitry Andric }
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
4040b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
4050b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
4110b57cec5SDimitry Andric   IO.mapRequired("Program", Symbol.Program);
4120b57cec5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4130b57cec5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
4170b57cec5SDimitry Andric   IO.mapRequired("Program", Symbol.Program);
4180b57cec5SDimitry Andric   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
4190b57cec5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4200b57cec5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
4240b57cec5SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
4250b57cec5SDimitry Andric   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
4260b57cec5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4270b57cec5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
4318bcb0991SDimitry Andric   IO.mapRequired("Offset", Symbol.Hdr.Offset);
4320b57cec5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4330b57cec5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
4370b57cec5SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
4380b57cec5SDimitry Andric   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
4390b57cec5SDimitry Andric   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
4400b57cec5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4410b57cec5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
4420b57cec5SDimitry Andric }
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric template <>
4450b57cec5SDimitry Andric void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
4460b57cec5SDimitry Andric   IO.mapRequired("Register", Symbol.Offset);
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
4500b57cec5SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
4510b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Hdr.Flags);
4520b57cec5SDimitry Andric   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
4530b57cec5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4540b57cec5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
4550b57cec5SDimitry Andric }
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
4580b57cec5SDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
4590b57cec5SDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
4600b57cec5SDimitry Andric   IO.mapRequired("CodeSize", Symbol.CodeSize);
4610b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
4620b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
4630b57cec5SDimitry Andric   IO.mapRequired("BlockName", Symbol.Name);
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
4670b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
4680b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
4690b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
4700b57cec5SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
4740b57cec5SDimitry Andric   IO.mapRequired("Signature", Symbol.Signature);
4750b57cec5SDimitry Andric   IO.mapRequired("ObjectName", Symbol.Name);
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
4790b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
4800b57cec5SDimitry Andric   IO.mapRequired("Machine", Symbol.Machine);
4810b57cec5SDimitry Andric   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
4820b57cec5SDimitry Andric   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
4830b57cec5SDimitry Andric   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
4840b57cec5SDimitry Andric   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
4850b57cec5SDimitry Andric   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
4860b57cec5SDimitry Andric   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
4870b57cec5SDimitry Andric   IO.mapRequired("Version", Symbol.Version);
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
4910b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
4920b57cec5SDimitry Andric   IO.mapRequired("Machine", Symbol.Machine);
4930b57cec5SDimitry Andric   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
4940b57cec5SDimitry Andric   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
4950b57cec5SDimitry Andric   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
4960b57cec5SDimitry Andric   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
4970b57cec5SDimitry Andric   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
4980b57cec5SDimitry Andric   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
4990b57cec5SDimitry Andric   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
5000b57cec5SDimitry Andric   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
5010b57cec5SDimitry Andric   IO.mapRequired("Version", Symbol.Version);
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
5050b57cec5SDimitry Andric   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
5060b57cec5SDimitry Andric   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
5070b57cec5SDimitry Andric   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
5080b57cec5SDimitry Andric   IO.mapRequired("BytesOfCalleeSavedRegisters",
5090b57cec5SDimitry Andric                  Symbol.BytesOfCalleeSavedRegisters);
5100b57cec5SDimitry Andric   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
5110b57cec5SDimitry Andric   IO.mapRequired("SectionIdOfExceptionHandler",
5120b57cec5SDimitry Andric                  Symbol.SectionIdOfExceptionHandler);
5130b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
5170b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
5180b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5190b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
5230b57cec5SDimitry Andric   IO.mapRequired("Index", Symbol.Index);
5240b57cec5SDimitry Andric   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
5250b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
5260b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
5300b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
5310b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5320b57cec5SDimitry Andric   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
5330b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
5370b57cec5SDimitry Andric   IO.mapRequired("Register", Symbol.Register);
5380b57cec5SDimitry Andric   IO.mapRequired("CookieKind", Symbol.CookieKind);
5390b57cec5SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
5400b57cec5SDimitry Andric }
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
5430b57cec5SDimitry Andric   IO.mapRequired("FuncID", Symbol.Indices);
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
5470b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5480b57cec5SDimitry Andric   IO.mapRequired("UDTName", Symbol.Name);
5490b57cec5SDimitry Andric }
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
5520b57cec5SDimitry Andric   IO.mapRequired("BuildId", Symbol.BuildId);
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
5560b57cec5SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
5570b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5580b57cec5SDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
5590b57cec5SDimitry Andric }
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
5620b57cec5SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
5630b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5640b57cec5SDimitry Andric   IO.mapRequired("Register", Symbol.Register);
5650b57cec5SDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
5690b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5700b57cec5SDimitry Andric   IO.mapRequired("Value", Symbol.Value);
5710b57cec5SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
5750b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5760b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
5770b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5780b57cec5SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
5820b57cec5SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
5830b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
5840b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5850b57cec5SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
5860b57cec5SDimitry Andric }
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
5890b57cec5SDimitry Andric   IO.mapRequired("Namespace", Symbol.Name);
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
5930b57cec5SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
5940b57cec5SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5950b57cec5SDimitry Andric   IO.mapRequired("Strings", Symbol.Strings);
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric 
598*5f757f3fSDimitry Andric template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) {
599*5f757f3fSDimitry Andric   IO.mapRequired("BaseOffset", Symbol.BaseOffset);
600*5f757f3fSDimitry Andric   IO.mapRequired("BaseSegment", Symbol.BaseSegment);
601*5f757f3fSDimitry Andric   IO.mapRequired("SwitchType", Symbol.SwitchType);
602*5f757f3fSDimitry Andric   IO.mapRequired("BranchOffset", Symbol.BranchOffset);
603*5f757f3fSDimitry Andric   IO.mapRequired("TableOffset", Symbol.TableOffset);
604*5f757f3fSDimitry Andric   IO.mapRequired("BranchSegment", Symbol.BranchSegment);
605*5f757f3fSDimitry Andric   IO.mapRequired("TableSegment", Symbol.TableSegment);
606*5f757f3fSDimitry Andric   IO.mapRequired("EntriesCount", Symbol.EntriesCount);
607*5f757f3fSDimitry Andric }
608*5f757f3fSDimitry Andric 
6090b57cec5SDimitry Andric } // end namespace detail
6100b57cec5SDimitry Andric } // end namespace CodeViewYAML
6110b57cec5SDimitry Andric } // end namespace llvm
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
6140b57cec5SDimitry Andric     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
6150b57cec5SDimitry Andric   return Symbol->toCodeViewSymbol(Allocator, Container);
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric namespace llvm {
6190b57cec5SDimitry Andric namespace yaml {
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric template <> struct MappingTraits<SymbolRecordBase> {
6220b57cec5SDimitry Andric   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
6230b57cec5SDimitry Andric };
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric } // end namespace yaml
6260b57cec5SDimitry Andric } // end namespace llvm
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric template <typename SymbolType>
6290b57cec5SDimitry Andric static inline Expected<CodeViewYAML::SymbolRecord>
6300b57cec5SDimitry Andric fromCodeViewSymbolImpl(CVSymbol Symbol) {
6310b57cec5SDimitry Andric   CodeViewYAML::SymbolRecord Result;
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
6340b57cec5SDimitry Andric   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
6350b57cec5SDimitry Andric     return std::move(EC);
6360b57cec5SDimitry Andric   Result.Symbol = Impl;
6370b57cec5SDimitry Andric   return Result;
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric Expected<CodeViewYAML::SymbolRecord>
6410b57cec5SDimitry Andric CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
6420b57cec5SDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
6430b57cec5SDimitry Andric   case EnumName:                                                               \
6440b57cec5SDimitry Andric     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
6450b57cec5SDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
6460b57cec5SDimitry Andric   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
6470b57cec5SDimitry Andric   switch (Symbol.kind()) {
6480b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
6490b57cec5SDimitry Andric   default:
6500b57cec5SDimitry Andric     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
6510b57cec5SDimitry Andric   }
6520b57cec5SDimitry Andric   return make_error<CodeViewError>(cv_error_code::corrupt_record);
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric template <typename ConcreteType>
6560b57cec5SDimitry Andric static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
6570b57cec5SDimitry Andric                                 CodeViewYAML::SymbolRecord &Obj) {
6580b57cec5SDimitry Andric   if (!IO.outputting())
6590b57cec5SDimitry Andric     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   IO.mapRequired(Class, *Obj.Symbol);
6620b57cec5SDimitry Andric }
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
6650b57cec5SDimitry Andric     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
6660b57cec5SDimitry Andric   SymbolKind Kind;
6670b57cec5SDimitry Andric   if (IO.outputting())
6680b57cec5SDimitry Andric     Kind = Obj.Symbol->Kind;
6690b57cec5SDimitry Andric   IO.mapRequired("Kind", Kind);
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
6720b57cec5SDimitry Andric   case EnumName:                                                               \
6730b57cec5SDimitry Andric     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
6740b57cec5SDimitry Andric                                                      Obj);                     \
6750b57cec5SDimitry Andric     break;
6760b57cec5SDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
6770b57cec5SDimitry Andric   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
6780b57cec5SDimitry Andric   switch (Kind) {
6790b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
6800b57cec5SDimitry Andric   default:
6810b57cec5SDimitry Andric     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
6820b57cec5SDimitry Andric   }
6830b57cec5SDimitry Andric }
684