11b88f4f3SZachary Turner //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
21b88f4f3SZachary Turner //
31b88f4f3SZachary Turner //                     The LLVM Compiler Infrastructure
41b88f4f3SZachary Turner //
51b88f4f3SZachary Turner // This file is distributed under the University of Illinois Open Source
61b88f4f3SZachary Turner // License. See LICENSE.TXT for details.
71b88f4f3SZachary Turner //
81b88f4f3SZachary Turner //===----------------------------------------------------------------------===//
91b88f4f3SZachary Turner //
101b88f4f3SZachary Turner // This file defines classes for handling the YAML representation of CodeView
111b88f4f3SZachary Turner // Debug Info.
121b88f4f3SZachary Turner //
131b88f4f3SZachary Turner //===----------------------------------------------------------------------===//
141b88f4f3SZachary Turner 
151b88f4f3SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
1628082ab0SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
1728082ab0SEugene Zelenko #include "llvm/ADT/StringRef.h"
1828082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/CodeView.h"
191b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h"
201b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h"
2128082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
221b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
2328082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
241b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
2528082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/TypeIndex.h"
2628082ab0SEugene Zelenko #include "llvm/ObjectYAML/YAML.h"
2728082ab0SEugene Zelenko #include "llvm/Support/Allocator.h"
2828082ab0SEugene Zelenko #include "llvm/Support/Error.h"
2928082ab0SEugene Zelenko #include "llvm/Support/YAMLTraits.h"
3028082ab0SEugene Zelenko #include <algorithm>
3128082ab0SEugene Zelenko #include <cstdint>
3228082ab0SEugene Zelenko #include <cstring>
3328082ab0SEugene Zelenko #include <string>
3428082ab0SEugene Zelenko #include <vector>
351b88f4f3SZachary Turner 
361b88f4f3SZachary Turner using namespace llvm;
371b88f4f3SZachary Turner using namespace llvm::codeview;
381b88f4f3SZachary Turner using namespace llvm::CodeViewYAML;
391b88f4f3SZachary Turner using namespace llvm::CodeViewYAML::detail;
401b88f4f3SZachary Turner using namespace llvm::yaml;
411b88f4f3SZachary Turner 
421b88f4f3SZachary Turner LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
4359468f5aSZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
441b88f4f3SZachary Turner 
451b88f4f3SZachary Turner // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
46b213b27eSFrancis Visoiu Mistrih LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
47b213b27eSFrancis Visoiu Mistrih LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
481b88f4f3SZachary Turner 
491b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
5063055455SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
511b88f4f3SZachary Turner 
521b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
531b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
541b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
5518d90e17SReid Kleckner LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
561b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
571b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
581b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
591b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
601b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
611b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
621b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
631b88f4f3SZachary Turner 
6428082ab0SEugene Zelenko LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
65349c18f8SZachary Turner 
66b213b27eSFrancis Visoiu Mistrih LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
67349c18f8SZachary Turner 
68349c18f8SZachary Turner StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
69349c18f8SZachary Turner   return ScalarTraits<StringRef>::input(S, V, T.value);
70349c18f8SZachary Turner }
7128082ab0SEugene Zelenko 
72349c18f8SZachary Turner void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
7328082ab0SEugene Zelenko                                     raw_ostream &R) {
74349c18f8SZachary Turner   ScalarTraits<StringRef>::output(T.value, V, R);
75349c18f8SZachary Turner }
76349c18f8SZachary Turner 
771b88f4f3SZachary Turner void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
781b88f4f3SZachary Turner                                                       SymbolKind &Value) {
791b88f4f3SZachary Turner   auto SymbolNames = getSymbolTypeNames();
801b88f4f3SZachary Turner   for (const auto &E : SymbolNames)
811b88f4f3SZachary Turner     io.enumCase(Value, E.Name.str().c_str(), E.Value);
821b88f4f3SZachary Turner }
831b88f4f3SZachary Turner 
841b88f4f3SZachary Turner void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
851b88f4f3SZachary Turner                                                   CompileSym2Flags &Flags) {
861b88f4f3SZachary Turner   auto FlagNames = getCompileSym2FlagNames();
871b88f4f3SZachary Turner   for (const auto &E : FlagNames) {
881b88f4f3SZachary Turner     io.bitSetCase(Flags, E.Name.str().c_str(),
891b88f4f3SZachary Turner                   static_cast<CompileSym2Flags>(E.Value));
901b88f4f3SZachary Turner   }
911b88f4f3SZachary Turner }
921b88f4f3SZachary Turner 
931b88f4f3SZachary Turner void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
941b88f4f3SZachary Turner                                                   CompileSym3Flags &Flags) {
951b88f4f3SZachary Turner   auto FlagNames = getCompileSym3FlagNames();
961b88f4f3SZachary Turner   for (const auto &E : FlagNames) {
971b88f4f3SZachary Turner     io.bitSetCase(Flags, E.Name.str().c_str(),
981b88f4f3SZachary Turner                   static_cast<CompileSym3Flags>(E.Value));
991b88f4f3SZachary Turner   }
1001b88f4f3SZachary Turner }
1011b88f4f3SZachary Turner 
1021b88f4f3SZachary Turner void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
1031b88f4f3SZachary Turner   auto FlagNames = getExportSymFlagNames();
1041b88f4f3SZachary Turner   for (const auto &E : FlagNames) {
1051b88f4f3SZachary Turner     io.bitSetCase(Flags, E.Name.str().c_str(),
1061b88f4f3SZachary Turner                   static_cast<ExportFlags>(E.Value));
1071b88f4f3SZachary Turner   }
1081b88f4f3SZachary Turner }
1091b88f4f3SZachary Turner 
11018d90e17SReid Kleckner void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
11118d90e17SReid Kleckner   auto FlagNames = getProcSymFlagNames();
11218d90e17SReid Kleckner   for (const auto &E : FlagNames) {
11318d90e17SReid Kleckner     io.bitSetCase(Flags, E.Name.str().c_str(),
11418d90e17SReid Kleckner                   static_cast<PublicSymFlags>(E.Value));
11518d90e17SReid Kleckner   }
11618d90e17SReid Kleckner }
11718d90e17SReid Kleckner 
1181b88f4f3SZachary Turner void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
1191b88f4f3SZachary Turner   auto FlagNames = getLocalFlagNames();
1201b88f4f3SZachary Turner   for (const auto &E : FlagNames) {
1211b88f4f3SZachary Turner     io.bitSetCase(Flags, E.Name.str().c_str(),
1221b88f4f3SZachary Turner                   static_cast<LocalSymFlags>(E.Value));
1231b88f4f3SZachary Turner   }
1241b88f4f3SZachary Turner }
1251b88f4f3SZachary Turner 
1261b88f4f3SZachary Turner void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
1271b88f4f3SZachary Turner   auto FlagNames = getProcSymFlagNames();
1281b88f4f3SZachary Turner   for (const auto &E : FlagNames) {
1291b88f4f3SZachary Turner     io.bitSetCase(Flags, E.Name.str().c_str(),
1301b88f4f3SZachary Turner                   static_cast<ProcSymFlags>(E.Value));
1311b88f4f3SZachary Turner   }
1321b88f4f3SZachary Turner }
1331b88f4f3SZachary Turner 
1341b88f4f3SZachary Turner void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
1351b88f4f3SZachary Turner     IO &io, FrameProcedureOptions &Flags) {
1361b88f4f3SZachary Turner   auto FlagNames = getFrameProcSymFlagNames();
1371b88f4f3SZachary Turner   for (const auto &E : FlagNames) {
1381b88f4f3SZachary Turner     io.bitSetCase(Flags, E.Name.str().c_str(),
1391b88f4f3SZachary Turner                   static_cast<FrameProcedureOptions>(E.Value));
1401b88f4f3SZachary Turner   }
1411b88f4f3SZachary Turner }
1421b88f4f3SZachary Turner 
1431b88f4f3SZachary Turner void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
1441b88f4f3SZachary Turner   auto CpuNames = getCPUTypeNames();
1451b88f4f3SZachary Turner   for (const auto &E : CpuNames) {
1461b88f4f3SZachary Turner     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
1471b88f4f3SZachary Turner   }
1481b88f4f3SZachary Turner }
1491b88f4f3SZachary Turner 
1501b88f4f3SZachary Turner void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
1511b88f4f3SZachary Turner   auto RegNames = getRegisterNames();
1521b88f4f3SZachary Turner   for (const auto &E : RegNames) {
1531b88f4f3SZachary Turner     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
1541b88f4f3SZachary Turner   }
1551b88f4f3SZachary Turner   io.enumFallback<Hex16>(Reg);
1561b88f4f3SZachary Turner }
1571b88f4f3SZachary Turner 
1581b88f4f3SZachary Turner void ScalarEnumerationTraits<TrampolineType>::enumeration(
1591b88f4f3SZachary Turner     IO &io, TrampolineType &Tramp) {
1601b88f4f3SZachary Turner   auto TrampNames = getTrampolineNames();
1611b88f4f3SZachary Turner   for (const auto &E : TrampNames) {
1621b88f4f3SZachary Turner     io.enumCase(Tramp, E.Name.str().c_str(),
1631b88f4f3SZachary Turner                 static_cast<TrampolineType>(E.Value));
1641b88f4f3SZachary Turner   }
1651b88f4f3SZachary Turner }
1661b88f4f3SZachary Turner 
1671b88f4f3SZachary Turner void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
1681b88f4f3SZachary Turner                                                         ThunkOrdinal &Ord) {
1691b88f4f3SZachary Turner   auto ThunkNames = getThunkOrdinalNames();
1701b88f4f3SZachary Turner   for (const auto &E : ThunkNames) {
1711b88f4f3SZachary Turner     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
1721b88f4f3SZachary Turner   }
1731b88f4f3SZachary Turner }
1741b88f4f3SZachary Turner 
17563055455SZachary Turner void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
17663055455SZachary Turner     IO &io, FrameCookieKind &FC) {
17763055455SZachary Turner   auto ThunkNames = getFrameCookieKindNames();
17863055455SZachary Turner   for (const auto &E : ThunkNames) {
17963055455SZachary Turner     io.enumCase(FC, E.Name.str().c_str(),
18063055455SZachary Turner                 static_cast<FrameCookieKind>(E.Value));
18163055455SZachary Turner   }
18263055455SZachary Turner }
18363055455SZachary Turner 
1841b88f4f3SZachary Turner namespace llvm {
18559468f5aSZachary Turner namespace yaml {
18659468f5aSZachary Turner template <> struct MappingTraits<LocalVariableAddrRange> {
18759468f5aSZachary Turner   static void mapping(IO &io, LocalVariableAddrRange &Range) {
18859468f5aSZachary Turner     io.mapRequired("OffsetStart", Range.OffsetStart);
18959468f5aSZachary Turner     io.mapRequired("ISectStart", Range.ISectStart);
19059468f5aSZachary Turner     io.mapRequired("Range", Range.Range);
19159468f5aSZachary Turner   }
19259468f5aSZachary Turner };
19359468f5aSZachary Turner template <> struct MappingTraits<LocalVariableAddrGap> {
19459468f5aSZachary Turner   static void mapping(IO &io, LocalVariableAddrGap &Gap) {
19559468f5aSZachary Turner     io.mapRequired("GapStartOffset", Gap.GapStartOffset);
19659468f5aSZachary Turner     io.mapRequired("Range", Gap.Range);
19759468f5aSZachary Turner   }
19859468f5aSZachary Turner };
19959468f5aSZachary Turner } // namespace yaml
20059468f5aSZachary Turner } // namespace llvm
20159468f5aSZachary Turner 
20259468f5aSZachary Turner namespace llvm {
2031b88f4f3SZachary Turner namespace CodeViewYAML {
2041b88f4f3SZachary Turner namespace detail {
2051b88f4f3SZachary Turner 
2061b88f4f3SZachary Turner struct SymbolRecordBase {
2071b88f4f3SZachary Turner   codeview::SymbolKind Kind;
2081b88f4f3SZachary Turner 
20928082ab0SEugene Zelenko   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
21028082ab0SEugene Zelenko   virtual ~SymbolRecordBase() = default;
21128082ab0SEugene Zelenko 
2121b88f4f3SZachary Turner   virtual void map(yaml::IO &io) = 0;
2131b88f4f3SZachary Turner   virtual codeview::CVSymbol
214ebd3ae83SZachary Turner   toCodeViewSymbol(BumpPtrAllocator &Allocator,
215ebd3ae83SZachary Turner                    CodeViewContainer Container) const = 0;
2161b88f4f3SZachary Turner   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
2171b88f4f3SZachary Turner };
2181b88f4f3SZachary Turner 
2191b88f4f3SZachary Turner template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
2201b88f4f3SZachary Turner   explicit SymbolRecordImpl(codeview::SymbolKind K)
2211b88f4f3SZachary Turner       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
2221b88f4f3SZachary Turner 
2231b88f4f3SZachary Turner   void map(yaml::IO &io) override;
2241b88f4f3SZachary Turner 
2251b88f4f3SZachary Turner   codeview::CVSymbol
226ebd3ae83SZachary Turner   toCodeViewSymbol(BumpPtrAllocator &Allocator,
227ebd3ae83SZachary Turner                    CodeViewContainer Container) const override {
228ebd3ae83SZachary Turner     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
2291b88f4f3SZachary Turner   }
23028082ab0SEugene Zelenko 
2311b88f4f3SZachary Turner   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
2321b88f4f3SZachary Turner     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
2331b88f4f3SZachary Turner   }
2341b88f4f3SZachary Turner 
2351b88f4f3SZachary Turner   mutable T Symbol;
2361b88f4f3SZachary Turner };
2371b88f4f3SZachary Turner 
238606d7665SZachary Turner struct UnknownSymbolRecord : public SymbolRecordBase {
239606d7665SZachary Turner   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
240606d7665SZachary Turner 
241606d7665SZachary Turner   void map(yaml::IO &io) override;
242606d7665SZachary Turner 
243606d7665SZachary Turner   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
244606d7665SZachary Turner                             CodeViewContainer Container) const override {
245606d7665SZachary Turner     RecordPrefix Prefix;
246606d7665SZachary Turner     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
247606d7665SZachary Turner     Prefix.RecordKind = Kind;
248606d7665SZachary Turner     Prefix.RecordLen = TotalLen - 2;
249606d7665SZachary Turner     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
250606d7665SZachary Turner     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
251606d7665SZachary Turner     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
252606d7665SZachary Turner     return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
253606d7665SZachary Turner   }
25428082ab0SEugene Zelenko 
255606d7665SZachary Turner   Error fromCodeViewSymbol(CVSymbol CVS) override {
256606d7665SZachary Turner     this->Kind = CVS.kind();
257606d7665SZachary Turner     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
258606d7665SZachary Turner     return Error::success();
259606d7665SZachary Turner   }
260606d7665SZachary Turner 
261606d7665SZachary Turner   std::vector<uint8_t> Data;
262606d7665SZachary Turner };
263606d7665SZachary Turner 
2641b88f4f3SZachary Turner template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
2651b88f4f3SZachary Turner 
266606d7665SZachary Turner void UnknownSymbolRecord::map(yaml::IO &io) {
267606d7665SZachary Turner   yaml::BinaryRef Binary;
268606d7665SZachary Turner   if (io.outputting())
269606d7665SZachary Turner     Binary = yaml::BinaryRef(Data);
270606d7665SZachary Turner   io.mapRequired("Data", Binary);
271606d7665SZachary Turner   if (!io.outputting()) {
272606d7665SZachary Turner     std::string Str;
273606d7665SZachary Turner     raw_string_ostream OS(Str);
274606d7665SZachary Turner     Binary.writeAsBinary(OS);
275606d7665SZachary Turner     OS.flush();
276606d7665SZachary Turner     Data.assign(Str.begin(), Str.end());
277606d7665SZachary Turner   }
278606d7665SZachary Turner }
279606d7665SZachary Turner 
2801b88f4f3SZachary Turner template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
2811b88f4f3SZachary Turner   IO.mapRequired("Parent", Symbol.Parent);
2821b88f4f3SZachary Turner   IO.mapRequired("End", Symbol.End);
2831b88f4f3SZachary Turner   IO.mapRequired("Next", Symbol.Next);
2841b88f4f3SZachary Turner   IO.mapRequired("Off", Symbol.Offset);
2851b88f4f3SZachary Turner   IO.mapRequired("Seg", Symbol.Segment);
2861b88f4f3SZachary Turner   IO.mapRequired("Len", Symbol.Length);
2871b88f4f3SZachary Turner   IO.mapRequired("Ordinal", Symbol.Thunk);
2881b88f4f3SZachary Turner }
2891b88f4f3SZachary Turner 
2901b88f4f3SZachary Turner template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
2911b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
2921b88f4f3SZachary Turner   IO.mapRequired("Size", Symbol.Size);
2931b88f4f3SZachary Turner   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
2941b88f4f3SZachary Turner   IO.mapRequired("TargetOff", Symbol.TargetOffset);
2951b88f4f3SZachary Turner   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
2961b88f4f3SZachary Turner   IO.mapRequired("TargetSection", Symbol.TargetSection);
2971b88f4f3SZachary Turner }
2981b88f4f3SZachary Turner 
2991b88f4f3SZachary Turner template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
3001b88f4f3SZachary Turner   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
3011b88f4f3SZachary Turner   IO.mapRequired("Alignment", Symbol.Alignment);
3021b88f4f3SZachary Turner   IO.mapRequired("Rva", Symbol.Rva);
3031b88f4f3SZachary Turner   IO.mapRequired("Length", Symbol.Length);
3041b88f4f3SZachary Turner   IO.mapRequired("Characteristics", Symbol.Characteristics);
3051b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
3061b88f4f3SZachary Turner }
3071b88f4f3SZachary Turner 
3081b88f4f3SZachary Turner template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
3091b88f4f3SZachary Turner   IO.mapRequired("Size", Symbol.Size);
3101b88f4f3SZachary Turner   IO.mapRequired("Characteristics", Symbol.Characteristics);
3111b88f4f3SZachary Turner   IO.mapRequired("Offset", Symbol.Offset);
3121b88f4f3SZachary Turner   IO.mapRequired("Segment", Symbol.Segment);
3131b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
3141b88f4f3SZachary Turner }
3151b88f4f3SZachary Turner 
3161b88f4f3SZachary Turner template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
3171b88f4f3SZachary Turner   IO.mapRequired("Ordinal", Symbol.Ordinal);
3181b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
3191b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
3201b88f4f3SZachary Turner }
3211b88f4f3SZachary Turner 
3221b88f4f3SZachary Turner template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
32391ef9de6SReid Kleckner   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
32491ef9de6SReid Kleckner   IO.mapOptional("PtrEnd", Symbol.End, 0U);
32591ef9de6SReid Kleckner   IO.mapOptional("PtrNext", Symbol.Next, 0U);
3261b88f4f3SZachary Turner   IO.mapRequired("CodeSize", Symbol.CodeSize);
3271b88f4f3SZachary Turner   IO.mapRequired("DbgStart", Symbol.DbgStart);
3281b88f4f3SZachary Turner   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
3291b88f4f3SZachary Turner   IO.mapRequired("FunctionType", Symbol.FunctionType);
33091ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
33191ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
3321b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
3331b88f4f3SZachary Turner   IO.mapRequired("DisplayName", Symbol.Name);
3341b88f4f3SZachary Turner }
3351b88f4f3SZachary Turner 
3361b88f4f3SZachary Turner template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
3371b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Index);
3381b88f4f3SZachary Turner   IO.mapRequired("Seg", Symbol.Register);
3391b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
3401b88f4f3SZachary Turner }
3411b88f4f3SZachary Turner 
3421b88f4f3SZachary Turner template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
34318d90e17SReid Kleckner   IO.mapRequired("Flags", Symbol.Flags);
34491ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.Offset, 0U);
34591ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
3461b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
3471b88f4f3SZachary Turner }
3481b88f4f3SZachary Turner 
3491b88f4f3SZachary Turner template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
3501b88f4f3SZachary Turner   IO.mapRequired("SumName", Symbol.SumName);
3511b88f4f3SZachary Turner   IO.mapRequired("SymOffset", Symbol.SymOffset);
3521b88f4f3SZachary Turner   IO.mapRequired("Mod", Symbol.Module);
3531b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
3541b88f4f3SZachary Turner }
3551b88f4f3SZachary Turner 
3561b88f4f3SZachary Turner template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
3571b88f4f3SZachary Turner   IO.mapRequired("Entries", Symbol.Fields);
3581b88f4f3SZachary Turner }
3591b88f4f3SZachary Turner 
3601b88f4f3SZachary Turner template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
36191ef9de6SReid Kleckner   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
36291ef9de6SReid Kleckner   IO.mapOptional("PtrEnd", Symbol.End, 0U);
3631b88f4f3SZachary Turner   IO.mapRequired("Inlinee", Symbol.Inlinee);
3641b88f4f3SZachary Turner   // TODO: The binary annotations
3651b88f4f3SZachary Turner }
3661b88f4f3SZachary Turner 
3671b88f4f3SZachary Turner template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
3681b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
3691b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
370349c18f8SZachary Turner 
3711b88f4f3SZachary Turner   IO.mapRequired("VarName", Symbol.Name);
3721b88f4f3SZachary Turner }
3731b88f4f3SZachary Turner 
3741b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
37559468f5aSZachary Turner   IO.mapRequired("Program", Symbol.Program);
37659468f5aSZachary Turner   IO.mapRequired("Range", Symbol.Range);
37759468f5aSZachary Turner   IO.mapRequired("Gaps", Symbol.Gaps);
3781b88f4f3SZachary Turner }
3791b88f4f3SZachary Turner 
3801b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
38159468f5aSZachary Turner   IO.mapRequired("Program", Symbol.Program);
38259468f5aSZachary Turner   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
38359468f5aSZachary Turner   IO.mapRequired("Range", Symbol.Range);
38459468f5aSZachary Turner   IO.mapRequired("Gaps", Symbol.Gaps);
3851b88f4f3SZachary Turner }
3861b88f4f3SZachary Turner 
3871b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
38859468f5aSZachary Turner   IO.mapRequired("Register", Symbol.Hdr.Register);
38959468f5aSZachary Turner   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
39059468f5aSZachary Turner   IO.mapRequired("Range", Symbol.Range);
39159468f5aSZachary Turner   IO.mapRequired("Gaps", Symbol.Gaps);
3921b88f4f3SZachary Turner }
3931b88f4f3SZachary Turner 
3941b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
39559468f5aSZachary Turner   IO.mapRequired("Offset", Symbol.Offset);
39659468f5aSZachary Turner   IO.mapRequired("Range", Symbol.Range);
39759468f5aSZachary Turner   IO.mapRequired("Gaps", Symbol.Gaps);
3981b88f4f3SZachary Turner }
3991b88f4f3SZachary Turner 
4001b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
40159468f5aSZachary Turner   IO.mapRequired("Register", Symbol.Hdr.Register);
40259468f5aSZachary Turner   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
40359468f5aSZachary Turner   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
40459468f5aSZachary Turner   IO.mapRequired("Range", Symbol.Range);
40559468f5aSZachary Turner   IO.mapRequired("Gaps", Symbol.Gaps);
4061b88f4f3SZachary Turner }
4071b88f4f3SZachary Turner 
4081b88f4f3SZachary Turner template <>
4091b88f4f3SZachary Turner void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
41059468f5aSZachary Turner   IO.mapRequired("Register", Symbol.Offset);
4111b88f4f3SZachary Turner }
4121b88f4f3SZachary Turner 
4131b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
41459468f5aSZachary Turner   IO.mapRequired("Register", Symbol.Hdr.Register);
41559468f5aSZachary Turner   IO.mapRequired("Flags", Symbol.Hdr.Flags);
41659468f5aSZachary Turner   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
41759468f5aSZachary Turner   IO.mapRequired("Range", Symbol.Range);
41859468f5aSZachary Turner   IO.mapRequired("Gaps", Symbol.Gaps);
4191b88f4f3SZachary Turner }
4201b88f4f3SZachary Turner 
4211b88f4f3SZachary Turner template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
42291ef9de6SReid Kleckner   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
42391ef9de6SReid Kleckner   IO.mapOptional("PtrEnd", Symbol.End, 0U);
4241b88f4f3SZachary Turner   IO.mapRequired("CodeSize", Symbol.CodeSize);
42591ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
42691ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
4271b88f4f3SZachary Turner   IO.mapRequired("BlockName", Symbol.Name);
4281b88f4f3SZachary Turner }
4291b88f4f3SZachary Turner 
4301b88f4f3SZachary Turner template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
43191ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
43291ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
4331b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
4341b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
4351b88f4f3SZachary Turner   IO.mapRequired("DisplayName", Symbol.Name);
4361b88f4f3SZachary Turner }
4371b88f4f3SZachary Turner 
4381b88f4f3SZachary Turner template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
4391b88f4f3SZachary Turner   IO.mapRequired("Signature", Symbol.Signature);
4401b88f4f3SZachary Turner   IO.mapRequired("ObjectName", Symbol.Name);
4411b88f4f3SZachary Turner }
4421b88f4f3SZachary Turner 
4431b88f4f3SZachary Turner template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
4441b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
4451b88f4f3SZachary Turner   IO.mapRequired("Machine", Symbol.Machine);
4461b88f4f3SZachary Turner   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
4471b88f4f3SZachary Turner   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
4481b88f4f3SZachary Turner   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
4491b88f4f3SZachary Turner   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
4501b88f4f3SZachary Turner   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
4511b88f4f3SZachary Turner   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
4521b88f4f3SZachary Turner   IO.mapRequired("Version", Symbol.Version);
4531b88f4f3SZachary Turner }
4541b88f4f3SZachary Turner 
4551b88f4f3SZachary Turner template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
4561b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
4571b88f4f3SZachary Turner   IO.mapRequired("Machine", Symbol.Machine);
4581b88f4f3SZachary Turner   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
4591b88f4f3SZachary Turner   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
4601b88f4f3SZachary Turner   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
4611b88f4f3SZachary Turner   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
4621b88f4f3SZachary Turner   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
4631b88f4f3SZachary Turner   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
4641b88f4f3SZachary Turner   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
4651b88f4f3SZachary Turner   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
4661b88f4f3SZachary Turner   IO.mapRequired("Version", Symbol.Version);
4671b88f4f3SZachary Turner }
4681b88f4f3SZachary Turner 
4691b88f4f3SZachary Turner template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
4701b88f4f3SZachary Turner   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
4711b88f4f3SZachary Turner   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
4721b88f4f3SZachary Turner   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
4731b88f4f3SZachary Turner   IO.mapRequired("BytesOfCalleeSavedRegisters",
4741b88f4f3SZachary Turner                  Symbol.BytesOfCalleeSavedRegisters);
4751b88f4f3SZachary Turner   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
4761b88f4f3SZachary Turner   IO.mapRequired("SectionIdOfExceptionHandler",
4771b88f4f3SZachary Turner                  Symbol.SectionIdOfExceptionHandler);
4781b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
4791b88f4f3SZachary Turner }
4801b88f4f3SZachary Turner 
4811b88f4f3SZachary Turner template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
48291ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
48391ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
4841b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
4851b88f4f3SZachary Turner }
4861b88f4f3SZachary Turner 
4871b88f4f3SZachary Turner template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
4881b88f4f3SZachary Turner   IO.mapRequired("Index", Symbol.Index);
4891b88f4f3SZachary Turner   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
4901b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
4911b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
4921b88f4f3SZachary Turner }
4931b88f4f3SZachary Turner 
4941b88f4f3SZachary Turner template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
49591ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
49691ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
4971b88f4f3SZachary Turner   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
4981b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
4991b88f4f3SZachary Turner }
5001b88f4f3SZachary Turner 
5011b88f4f3SZachary Turner template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
5021b88f4f3SZachary Turner   IO.mapRequired("Register", Symbol.Register);
5031b88f4f3SZachary Turner   IO.mapRequired("CookieKind", Symbol.CookieKind);
5041b88f4f3SZachary Turner   IO.mapRequired("Flags", Symbol.Flags);
5051b88f4f3SZachary Turner }
5061b88f4f3SZachary Turner 
5071b88f4f3SZachary Turner template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
5081b88f4f3SZachary Turner   IO.mapRequired("FuncID", Symbol.Indices);
5091b88f4f3SZachary Turner }
5101b88f4f3SZachary Turner 
5111b88f4f3SZachary Turner template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
5121b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
5131b88f4f3SZachary Turner   IO.mapRequired("UDTName", Symbol.Name);
5141b88f4f3SZachary Turner }
5151b88f4f3SZachary Turner 
5161b88f4f3SZachary Turner template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
5171b88f4f3SZachary Turner   IO.mapRequired("BuildId", Symbol.BuildId);
5181b88f4f3SZachary Turner }
5191b88f4f3SZachary Turner 
5201b88f4f3SZachary Turner template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
5211b88f4f3SZachary Turner   IO.mapRequired("Offset", Symbol.Offset);
5221b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
5231b88f4f3SZachary Turner   IO.mapRequired("VarName", Symbol.Name);
5241b88f4f3SZachary Turner }
5251b88f4f3SZachary Turner 
5261b88f4f3SZachary Turner template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
5271b88f4f3SZachary Turner   IO.mapRequired("Offset", Symbol.Offset);
5281b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
5291b88f4f3SZachary Turner   IO.mapRequired("Register", Symbol.Register);
5301b88f4f3SZachary Turner   IO.mapRequired("VarName", Symbol.Name);
5311b88f4f3SZachary Turner }
5321b88f4f3SZachary Turner 
5331b88f4f3SZachary Turner template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
5341b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
5351b88f4f3SZachary Turner   IO.mapRequired("Value", Symbol.Value);
5361b88f4f3SZachary Turner   IO.mapRequired("Name", Symbol.Name);
5371b88f4f3SZachary Turner }
5381b88f4f3SZachary Turner 
5391b88f4f3SZachary Turner template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
5401b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
54191ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
542665e1c92SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5431b88f4f3SZachary Turner   IO.mapRequired("DisplayName", Symbol.Name);
5441b88f4f3SZachary Turner }
5451b88f4f3SZachary Turner 
5461b88f4f3SZachary Turner template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
5471b88f4f3SZachary Turner   IO.mapRequired("Type", Symbol.Type);
54891ef9de6SReid Kleckner   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
54991ef9de6SReid Kleckner   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
5501b88f4f3SZachary Turner   IO.mapRequired("DisplayName", Symbol.Name);
5511b88f4f3SZachary Turner }
55228082ab0SEugene Zelenko 
553*ee8a7200SAlexandre Ganea template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
554*ee8a7200SAlexandre Ganea   IO.mapRequired("Namespace", Symbol.Name);
555*ee8a7200SAlexandre Ganea }
556*ee8a7200SAlexandre Ganea 
55728082ab0SEugene Zelenko } // end namespace detail
55828082ab0SEugene Zelenko } // end namespace CodeViewYAML
55928082ab0SEugene Zelenko } // end namespace llvm
5601b88f4f3SZachary Turner 
5611b88f4f3SZachary Turner CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
562ebd3ae83SZachary Turner     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
563ebd3ae83SZachary Turner   return Symbol->toCodeViewSymbol(Allocator, Container);
5641b88f4f3SZachary Turner }
5651b88f4f3SZachary Turner 
5661b88f4f3SZachary Turner namespace llvm {
5671b88f4f3SZachary Turner namespace yaml {
56828082ab0SEugene Zelenko 
5691b88f4f3SZachary Turner template <> struct MappingTraits<SymbolRecordBase> {
5701b88f4f3SZachary Turner   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
5711b88f4f3SZachary Turner };
57228082ab0SEugene Zelenko 
57328082ab0SEugene Zelenko } // end namespace yaml
57428082ab0SEugene Zelenko } // end namespace llvm
5751b88f4f3SZachary Turner 
5761b88f4f3SZachary Turner template <typename SymbolType>
5771b88f4f3SZachary Turner static inline Expected<CodeViewYAML::SymbolRecord>
5781b88f4f3SZachary Turner fromCodeViewSymbolImpl(CVSymbol Symbol) {
5791b88f4f3SZachary Turner   CodeViewYAML::SymbolRecord Result;
5801b88f4f3SZachary Turner 
581606d7665SZachary Turner   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
5821b88f4f3SZachary Turner   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
5831b88f4f3SZachary Turner     return std::move(EC);
5841b88f4f3SZachary Turner   Result.Symbol = Impl;
5851b88f4f3SZachary Turner   return Result;
5861b88f4f3SZachary Turner }
5871b88f4f3SZachary Turner 
5881b88f4f3SZachary Turner Expected<CodeViewYAML::SymbolRecord>
5891b88f4f3SZachary Turner CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
5901b88f4f3SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
5911b88f4f3SZachary Turner   case EnumName:                                                               \
592606d7665SZachary Turner     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
5931b88f4f3SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
5941b88f4f3SZachary Turner   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
5951b88f4f3SZachary Turner   switch (Symbol.kind()) {
5961b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
597606d7665SZachary Turner   default:
598606d7665SZachary Turner     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
5991b88f4f3SZachary Turner   }
6001b88f4f3SZachary Turner   return make_error<CodeViewError>(cv_error_code::corrupt_record);
6011b88f4f3SZachary Turner }
6021b88f4f3SZachary Turner 
6031b88f4f3SZachary Turner template <typename ConcreteType>
6041b88f4f3SZachary Turner static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
6051b88f4f3SZachary Turner                                 CodeViewYAML::SymbolRecord &Obj) {
6061b88f4f3SZachary Turner   if (!IO.outputting())
607606d7665SZachary Turner     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
6081b88f4f3SZachary Turner 
6091b88f4f3SZachary Turner   IO.mapRequired(Class, *Obj.Symbol);
6101b88f4f3SZachary Turner }
6111b88f4f3SZachary Turner 
6121b88f4f3SZachary Turner void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
6131b88f4f3SZachary Turner     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
6141b88f4f3SZachary Turner   SymbolKind Kind;
6151b88f4f3SZachary Turner   if (IO.outputting())
6161b88f4f3SZachary Turner     Kind = Obj.Symbol->Kind;
6171b88f4f3SZachary Turner   IO.mapRequired("Kind", Kind);
6181b88f4f3SZachary Turner 
6191b88f4f3SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
6201b88f4f3SZachary Turner   case EnumName:                                                               \
621606d7665SZachary Turner     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
622606d7665SZachary Turner                                                      Obj);                     \
6231b88f4f3SZachary Turner     break;
6241b88f4f3SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
6251b88f4f3SZachary Turner   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
6261b88f4f3SZachary Turner   switch (Kind) {
6271b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
628606d7665SZachary Turner   default:
629606d7665SZachary Turner     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
6301b88f4f3SZachary Turner   }
6311b88f4f3SZachary Turner }
632