1f9448bf3SDimitry Andric //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2f9448bf3SDimitry Andric //
3f9448bf3SDimitry Andric //                     The LLVM Compiler Infrastructure
4f9448bf3SDimitry Andric //
5f9448bf3SDimitry Andric // This file is distributed under the University of Illinois Open Source
6f9448bf3SDimitry Andric // License. See LICENSE.TXT for details.
7f9448bf3SDimitry Andric //
8f9448bf3SDimitry Andric //===----------------------------------------------------------------------===//
9f9448bf3SDimitry Andric //
10f9448bf3SDimitry Andric // This file defines classes for handling the YAML representation of CodeView
11f9448bf3SDimitry Andric // Debug Info.
12f9448bf3SDimitry Andric //
13f9448bf3SDimitry Andric //===----------------------------------------------------------------------===//
14f9448bf3SDimitry Andric 
15f9448bf3SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
16a580b014SDimitry Andric #include "llvm/ADT/ArrayRef.h"
17a580b014SDimitry Andric #include "llvm/ADT/StringRef.h"
18a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
19f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
20f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/EnumTables.h"
21a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
22f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
23a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
24f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
25a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
26a580b014SDimitry Andric #include "llvm/ObjectYAML/YAML.h"
27a580b014SDimitry Andric #include "llvm/Support/Allocator.h"
28a580b014SDimitry Andric #include "llvm/Support/Error.h"
29a580b014SDimitry Andric #include "llvm/Support/YAMLTraits.h"
30a580b014SDimitry Andric #include <algorithm>
31a580b014SDimitry Andric #include <cstdint>
32a580b014SDimitry Andric #include <cstring>
33a580b014SDimitry Andric #include <string>
34a580b014SDimitry Andric #include <vector>
35f9448bf3SDimitry Andric 
36f9448bf3SDimitry Andric using namespace llvm;
37f9448bf3SDimitry Andric using namespace llvm::codeview;
38f9448bf3SDimitry Andric using namespace llvm::CodeViewYAML;
39f9448bf3SDimitry Andric using namespace llvm::CodeViewYAML::detail;
40f9448bf3SDimitry Andric using namespace llvm::yaml;
41f9448bf3SDimitry Andric 
42f9448bf3SDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)434ba319b5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
44f9448bf3SDimitry Andric 
45f9448bf3SDimitry Andric // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
462cab237bSDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
472cab237bSDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
48f9448bf3SDimitry Andric 
49f9448bf3SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
5024d58133SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
51f9448bf3SDimitry Andric 
52f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
53f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
54f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
55edd7eaddSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
56f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
57f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
58f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
59f9448bf3SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
60f9448bf3SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
61f9448bf3SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
62f9448bf3SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
63f9448bf3SDimitry Andric 
64a580b014SDimitry Andric LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
65db17bf38SDimitry Andric 
662cab237bSDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
67db17bf38SDimitry Andric 
68db17bf38SDimitry Andric StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
69db17bf38SDimitry Andric   return ScalarTraits<StringRef>::input(S, V, T.value);
70db17bf38SDimitry Andric }
71a580b014SDimitry Andric 
output(const TypeName & T,void * V,raw_ostream & R)72db17bf38SDimitry Andric void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
73a580b014SDimitry Andric                                     raw_ostream &R) {
74db17bf38SDimitry Andric   ScalarTraits<StringRef>::output(T.value, V, R);
75db17bf38SDimitry Andric }
76db17bf38SDimitry Andric 
enumeration(IO & io,SymbolKind & Value)77f9448bf3SDimitry Andric void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
78f9448bf3SDimitry Andric                                                       SymbolKind &Value) {
79f9448bf3SDimitry Andric   auto SymbolNames = getSymbolTypeNames();
80f9448bf3SDimitry Andric   for (const auto &E : SymbolNames)
81f9448bf3SDimitry Andric     io.enumCase(Value, E.Name.str().c_str(), E.Value);
82f9448bf3SDimitry Andric }
83f9448bf3SDimitry Andric 
bitset(IO & io,CompileSym2Flags & Flags)84f9448bf3SDimitry Andric void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
85f9448bf3SDimitry Andric                                                   CompileSym2Flags &Flags) {
86f9448bf3SDimitry Andric   auto FlagNames = getCompileSym2FlagNames();
87f9448bf3SDimitry Andric   for (const auto &E : FlagNames) {
88f9448bf3SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
89f9448bf3SDimitry Andric                   static_cast<CompileSym2Flags>(E.Value));
90f9448bf3SDimitry Andric   }
91f9448bf3SDimitry Andric }
92f9448bf3SDimitry Andric 
bitset(IO & io,CompileSym3Flags & Flags)93f9448bf3SDimitry Andric void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
94f9448bf3SDimitry Andric                                                   CompileSym3Flags &Flags) {
95f9448bf3SDimitry Andric   auto FlagNames = getCompileSym3FlagNames();
96f9448bf3SDimitry Andric   for (const auto &E : FlagNames) {
97f9448bf3SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
98f9448bf3SDimitry Andric                   static_cast<CompileSym3Flags>(E.Value));
99f9448bf3SDimitry Andric   }
100f9448bf3SDimitry Andric }
101f9448bf3SDimitry Andric 
bitset(IO & io,ExportFlags & Flags)102f9448bf3SDimitry Andric void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
103f9448bf3SDimitry Andric   auto FlagNames = getExportSymFlagNames();
104f9448bf3SDimitry Andric   for (const auto &E : FlagNames) {
105f9448bf3SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
106f9448bf3SDimitry Andric                   static_cast<ExportFlags>(E.Value));
107f9448bf3SDimitry Andric   }
108f9448bf3SDimitry Andric }
109f9448bf3SDimitry Andric 
bitset(IO & io,PublicSymFlags & Flags)110edd7eaddSDimitry Andric void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
111*b5893f02SDimitry Andric   auto FlagNames = getPublicSymFlagNames();
112edd7eaddSDimitry Andric   for (const auto &E : FlagNames) {
113edd7eaddSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
114edd7eaddSDimitry Andric                   static_cast<PublicSymFlags>(E.Value));
115edd7eaddSDimitry Andric   }
116edd7eaddSDimitry Andric }
117edd7eaddSDimitry Andric 
bitset(IO & io,LocalSymFlags & Flags)118f9448bf3SDimitry Andric void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
119f9448bf3SDimitry Andric   auto FlagNames = getLocalFlagNames();
120f9448bf3SDimitry Andric   for (const auto &E : FlagNames) {
121f9448bf3SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
122f9448bf3SDimitry Andric                   static_cast<LocalSymFlags>(E.Value));
123f9448bf3SDimitry Andric   }
124f9448bf3SDimitry Andric }
125f9448bf3SDimitry Andric 
bitset(IO & io,ProcSymFlags & Flags)126f9448bf3SDimitry Andric void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
127f9448bf3SDimitry Andric   auto FlagNames = getProcSymFlagNames();
128f9448bf3SDimitry Andric   for (const auto &E : FlagNames) {
129f9448bf3SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
130f9448bf3SDimitry Andric                   static_cast<ProcSymFlags>(E.Value));
131f9448bf3SDimitry Andric   }
132f9448bf3SDimitry Andric }
133f9448bf3SDimitry Andric 
bitset(IO & io,FrameProcedureOptions & Flags)134f9448bf3SDimitry Andric void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
135f9448bf3SDimitry Andric     IO &io, FrameProcedureOptions &Flags) {
136f9448bf3SDimitry Andric   auto FlagNames = getFrameProcSymFlagNames();
137f9448bf3SDimitry Andric   for (const auto &E : FlagNames) {
138f9448bf3SDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
139f9448bf3SDimitry Andric                   static_cast<FrameProcedureOptions>(E.Value));
140f9448bf3SDimitry Andric   }
141f9448bf3SDimitry Andric }
142f9448bf3SDimitry Andric 
enumeration(IO & io,CPUType & Cpu)143f9448bf3SDimitry Andric void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
144f9448bf3SDimitry Andric   auto CpuNames = getCPUTypeNames();
145f9448bf3SDimitry Andric   for (const auto &E : CpuNames) {
146f9448bf3SDimitry Andric     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
147f9448bf3SDimitry Andric   }
148f9448bf3SDimitry Andric }
149f9448bf3SDimitry Andric 
enumeration(IO & io,RegisterId & Reg)150f9448bf3SDimitry Andric void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
151f9448bf3SDimitry Andric   auto RegNames = getRegisterNames();
152f9448bf3SDimitry Andric   for (const auto &E : RegNames) {
153f9448bf3SDimitry Andric     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
154f9448bf3SDimitry Andric   }
155f9448bf3SDimitry Andric   io.enumFallback<Hex16>(Reg);
156f9448bf3SDimitry Andric }
157f9448bf3SDimitry Andric 
enumeration(IO & io,TrampolineType & Tramp)158f9448bf3SDimitry Andric void ScalarEnumerationTraits<TrampolineType>::enumeration(
159f9448bf3SDimitry Andric     IO &io, TrampolineType &Tramp) {
160f9448bf3SDimitry Andric   auto TrampNames = getTrampolineNames();
161f9448bf3SDimitry Andric   for (const auto &E : TrampNames) {
162f9448bf3SDimitry Andric     io.enumCase(Tramp, E.Name.str().c_str(),
163f9448bf3SDimitry Andric                 static_cast<TrampolineType>(E.Value));
164f9448bf3SDimitry Andric   }
165f9448bf3SDimitry Andric }
166f9448bf3SDimitry Andric 
enumeration(IO & io,ThunkOrdinal & Ord)167f9448bf3SDimitry Andric void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
168f9448bf3SDimitry Andric                                                         ThunkOrdinal &Ord) {
169f9448bf3SDimitry Andric   auto ThunkNames = getThunkOrdinalNames();
170f9448bf3SDimitry Andric   for (const auto &E : ThunkNames) {
171f9448bf3SDimitry Andric     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
172f9448bf3SDimitry Andric   }
173f9448bf3SDimitry Andric }
174f9448bf3SDimitry Andric 
enumeration(IO & io,FrameCookieKind & FC)17524d58133SDimitry Andric void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
17624d58133SDimitry Andric     IO &io, FrameCookieKind &FC) {
17724d58133SDimitry Andric   auto ThunkNames = getFrameCookieKindNames();
17824d58133SDimitry Andric   for (const auto &E : ThunkNames) {
17924d58133SDimitry Andric     io.enumCase(FC, E.Name.str().c_str(),
18024d58133SDimitry Andric                 static_cast<FrameCookieKind>(E.Value));
18124d58133SDimitry Andric   }
18224d58133SDimitry Andric }
18324d58133SDimitry Andric 
184f9448bf3SDimitry Andric namespace llvm {
1854ba319b5SDimitry Andric namespace yaml {
1864ba319b5SDimitry Andric template <> struct MappingTraits<LocalVariableAddrRange> {
mappingllvm::yaml::MappingTraits1874ba319b5SDimitry Andric   static void mapping(IO &io, LocalVariableAddrRange &Range) {
1884ba319b5SDimitry Andric     io.mapRequired("OffsetStart", Range.OffsetStart);
1894ba319b5SDimitry Andric     io.mapRequired("ISectStart", Range.ISectStart);
1904ba319b5SDimitry Andric     io.mapRequired("Range", Range.Range);
1914ba319b5SDimitry Andric   }
1924ba319b5SDimitry Andric };
1934ba319b5SDimitry Andric template <> struct MappingTraits<LocalVariableAddrGap> {
mappingllvm::yaml::MappingTraits1944ba319b5SDimitry Andric   static void mapping(IO &io, LocalVariableAddrGap &Gap) {
1954ba319b5SDimitry Andric     io.mapRequired("GapStartOffset", Gap.GapStartOffset);
1964ba319b5SDimitry Andric     io.mapRequired("Range", Gap.Range);
1974ba319b5SDimitry Andric   }
1984ba319b5SDimitry Andric };
1994ba319b5SDimitry Andric } // namespace yaml
2004ba319b5SDimitry Andric } // namespace llvm
2014ba319b5SDimitry Andric 
2024ba319b5SDimitry Andric namespace llvm {
203f9448bf3SDimitry Andric namespace CodeViewYAML {
204f9448bf3SDimitry Andric namespace detail {
205f9448bf3SDimitry Andric 
206f9448bf3SDimitry Andric struct SymbolRecordBase {
207f9448bf3SDimitry Andric   codeview::SymbolKind Kind;
208f9448bf3SDimitry Andric 
SymbolRecordBasellvm::CodeViewYAML::detail::SymbolRecordBase209a580b014SDimitry Andric   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
210a580b014SDimitry Andric   virtual ~SymbolRecordBase() = default;
211a580b014SDimitry Andric 
212f9448bf3SDimitry Andric   virtual void map(yaml::IO &io) = 0;
213f9448bf3SDimitry Andric   virtual codeview::CVSymbol
2146d97bb29SDimitry Andric   toCodeViewSymbol(BumpPtrAllocator &Allocator,
2156d97bb29SDimitry Andric                    CodeViewContainer Container) const = 0;
216f9448bf3SDimitry Andric   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
217f9448bf3SDimitry Andric };
218f9448bf3SDimitry Andric 
219f9448bf3SDimitry Andric template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
SymbolRecordImplllvm::CodeViewYAML::detail::SymbolRecordImpl220f9448bf3SDimitry Andric   explicit SymbolRecordImpl(codeview::SymbolKind K)
221f9448bf3SDimitry Andric       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
222f9448bf3SDimitry Andric 
223f9448bf3SDimitry Andric   void map(yaml::IO &io) override;
224f9448bf3SDimitry Andric 
225f9448bf3SDimitry Andric   codeview::CVSymbol
toCodeViewSymbolllvm::CodeViewYAML::detail::SymbolRecordImpl2266d97bb29SDimitry Andric   toCodeViewSymbol(BumpPtrAllocator &Allocator,
2276d97bb29SDimitry Andric                    CodeViewContainer Container) const override {
2286d97bb29SDimitry Andric     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
229f9448bf3SDimitry Andric   }
230a580b014SDimitry Andric 
fromCodeViewSymbolllvm::CodeViewYAML::detail::SymbolRecordImpl231f9448bf3SDimitry Andric   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
232f9448bf3SDimitry Andric     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
233f9448bf3SDimitry Andric   }
234f9448bf3SDimitry Andric 
235f9448bf3SDimitry Andric   mutable T Symbol;
236f9448bf3SDimitry Andric };
237f9448bf3SDimitry Andric 
23824d58133SDimitry Andric struct UnknownSymbolRecord : public SymbolRecordBase {
UnknownSymbolRecordllvm::CodeViewYAML::detail::UnknownSymbolRecord23924d58133SDimitry Andric   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
24024d58133SDimitry Andric 
24124d58133SDimitry Andric   void map(yaml::IO &io) override;
24224d58133SDimitry Andric 
toCodeViewSymbolllvm::CodeViewYAML::detail::UnknownSymbolRecord24324d58133SDimitry Andric   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
24424d58133SDimitry Andric                             CodeViewContainer Container) const override {
24524d58133SDimitry Andric     RecordPrefix Prefix;
24624d58133SDimitry Andric     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
24724d58133SDimitry Andric     Prefix.RecordKind = Kind;
24824d58133SDimitry Andric     Prefix.RecordLen = TotalLen - 2;
24924d58133SDimitry Andric     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
25024d58133SDimitry Andric     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
25124d58133SDimitry Andric     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
25224d58133SDimitry Andric     return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
25324d58133SDimitry Andric   }
254a580b014SDimitry Andric 
fromCodeViewSymbolllvm::CodeViewYAML::detail::UnknownSymbolRecord25524d58133SDimitry Andric   Error fromCodeViewSymbol(CVSymbol CVS) override {
25624d58133SDimitry Andric     this->Kind = CVS.kind();
25724d58133SDimitry Andric     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
25824d58133SDimitry Andric     return Error::success();
25924d58133SDimitry Andric   }
26024d58133SDimitry Andric 
26124d58133SDimitry Andric   std::vector<uint8_t> Data;
26224d58133SDimitry Andric };
26324d58133SDimitry Andric 
map(IO & IO)264f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
265f9448bf3SDimitry Andric 
map(yaml::IO & io)26624d58133SDimitry Andric void UnknownSymbolRecord::map(yaml::IO &io) {
26724d58133SDimitry Andric   yaml::BinaryRef Binary;
26824d58133SDimitry Andric   if (io.outputting())
26924d58133SDimitry Andric     Binary = yaml::BinaryRef(Data);
27024d58133SDimitry Andric   io.mapRequired("Data", Binary);
27124d58133SDimitry Andric   if (!io.outputting()) {
27224d58133SDimitry Andric     std::string Str;
27324d58133SDimitry Andric     raw_string_ostream OS(Str);
27424d58133SDimitry Andric     Binary.writeAsBinary(OS);
27524d58133SDimitry Andric     OS.flush();
27624d58133SDimitry Andric     Data.assign(Str.begin(), Str.end());
27724d58133SDimitry Andric   }
27824d58133SDimitry Andric }
27924d58133SDimitry Andric 
map(IO & IO)280f9448bf3SDimitry Andric template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
281f9448bf3SDimitry Andric   IO.mapRequired("Parent", Symbol.Parent);
282f9448bf3SDimitry Andric   IO.mapRequired("End", Symbol.End);
283f9448bf3SDimitry Andric   IO.mapRequired("Next", Symbol.Next);
284f9448bf3SDimitry Andric   IO.mapRequired("Off", Symbol.Offset);
285f9448bf3SDimitry Andric   IO.mapRequired("Seg", Symbol.Segment);
286f9448bf3SDimitry Andric   IO.mapRequired("Len", Symbol.Length);
287f9448bf3SDimitry Andric   IO.mapRequired("Ordinal", Symbol.Thunk);
288f9448bf3SDimitry Andric }
289f9448bf3SDimitry Andric 
map(IO & IO)290f9448bf3SDimitry Andric template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
291f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
292f9448bf3SDimitry Andric   IO.mapRequired("Size", Symbol.Size);
293f9448bf3SDimitry Andric   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
294f9448bf3SDimitry Andric   IO.mapRequired("TargetOff", Symbol.TargetOffset);
295f9448bf3SDimitry Andric   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
296f9448bf3SDimitry Andric   IO.mapRequired("TargetSection", Symbol.TargetSection);
297f9448bf3SDimitry Andric }
298f9448bf3SDimitry Andric 
map(IO & IO)299f9448bf3SDimitry Andric template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
300f9448bf3SDimitry Andric   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
301f9448bf3SDimitry Andric   IO.mapRequired("Alignment", Symbol.Alignment);
302f9448bf3SDimitry Andric   IO.mapRequired("Rva", Symbol.Rva);
303f9448bf3SDimitry Andric   IO.mapRequired("Length", Symbol.Length);
304f9448bf3SDimitry Andric   IO.mapRequired("Characteristics", Symbol.Characteristics);
305f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
306f9448bf3SDimitry Andric }
307f9448bf3SDimitry Andric 
map(IO & IO)308f9448bf3SDimitry Andric template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
309f9448bf3SDimitry Andric   IO.mapRequired("Size", Symbol.Size);
310f9448bf3SDimitry Andric   IO.mapRequired("Characteristics", Symbol.Characteristics);
311f9448bf3SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
312f9448bf3SDimitry Andric   IO.mapRequired("Segment", Symbol.Segment);
313f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
314f9448bf3SDimitry Andric }
315f9448bf3SDimitry Andric 
map(IO & IO)316f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
317f9448bf3SDimitry Andric   IO.mapRequired("Ordinal", Symbol.Ordinal);
318f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
319f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
320f9448bf3SDimitry Andric }
321f9448bf3SDimitry Andric 
map(IO & IO)322f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
323edd7eaddSDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
324edd7eaddSDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
325edd7eaddSDimitry Andric   IO.mapOptional("PtrNext", Symbol.Next, 0U);
326f9448bf3SDimitry Andric   IO.mapRequired("CodeSize", Symbol.CodeSize);
327f9448bf3SDimitry Andric   IO.mapRequired("DbgStart", Symbol.DbgStart);
328f9448bf3SDimitry Andric   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
329f9448bf3SDimitry Andric   IO.mapRequired("FunctionType", Symbol.FunctionType);
330edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
331edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
332f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
333f9448bf3SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
334f9448bf3SDimitry Andric }
335f9448bf3SDimitry Andric 
map(IO & IO)336f9448bf3SDimitry Andric template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
337f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Index);
338f9448bf3SDimitry Andric   IO.mapRequired("Seg", Symbol.Register);
339f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
340f9448bf3SDimitry Andric }
341f9448bf3SDimitry Andric 
map(IO & IO)342f9448bf3SDimitry Andric template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
343edd7eaddSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
344edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.Offset, 0U);
345edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
346f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
347f9448bf3SDimitry Andric }
348f9448bf3SDimitry Andric 
map(IO & IO)349f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
350f9448bf3SDimitry Andric   IO.mapRequired("SumName", Symbol.SumName);
351f9448bf3SDimitry Andric   IO.mapRequired("SymOffset", Symbol.SymOffset);
352f9448bf3SDimitry Andric   IO.mapRequired("Mod", Symbol.Module);
353f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
354f9448bf3SDimitry Andric }
355f9448bf3SDimitry Andric 
map(IO & IO)356f9448bf3SDimitry Andric template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
357f9448bf3SDimitry Andric   IO.mapRequired("Entries", Symbol.Fields);
358f9448bf3SDimitry Andric }
359f9448bf3SDimitry Andric 
map(IO & IO)360f9448bf3SDimitry Andric template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
361edd7eaddSDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
362edd7eaddSDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
363f9448bf3SDimitry Andric   IO.mapRequired("Inlinee", Symbol.Inlinee);
364f9448bf3SDimitry Andric   // TODO: The binary annotations
365f9448bf3SDimitry Andric }
366f9448bf3SDimitry Andric 
map(IO & IO)367f9448bf3SDimitry Andric template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
368f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
369f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
370db17bf38SDimitry Andric 
371f9448bf3SDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
372f9448bf3SDimitry Andric }
373f9448bf3SDimitry Andric 
map(IO & IO)374f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
3754ba319b5SDimitry Andric   IO.mapRequired("Program", Symbol.Program);
3764ba319b5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
3774ba319b5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
378f9448bf3SDimitry Andric }
379f9448bf3SDimitry Andric 
map(IO & IO)380f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
3814ba319b5SDimitry Andric   IO.mapRequired("Program", Symbol.Program);
3824ba319b5SDimitry Andric   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
3834ba319b5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
3844ba319b5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
385f9448bf3SDimitry Andric }
386f9448bf3SDimitry Andric 
map(IO & IO)387f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
3884ba319b5SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
3894ba319b5SDimitry Andric   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
3904ba319b5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
3914ba319b5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
392f9448bf3SDimitry Andric }
393f9448bf3SDimitry Andric 
map(IO & IO)394f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
3954ba319b5SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
3964ba319b5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
3974ba319b5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
398f9448bf3SDimitry Andric }
399f9448bf3SDimitry Andric 
map(IO & IO)400f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
4014ba319b5SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
4024ba319b5SDimitry Andric   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
4034ba319b5SDimitry Andric   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
4044ba319b5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4054ba319b5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
406f9448bf3SDimitry Andric }
407f9448bf3SDimitry Andric 
408f9448bf3SDimitry Andric template <>
map(IO & IO)409f9448bf3SDimitry Andric void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
4104ba319b5SDimitry Andric   IO.mapRequired("Register", Symbol.Offset);
411f9448bf3SDimitry Andric }
412f9448bf3SDimitry Andric 
map(IO & IO)413f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
4144ba319b5SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
4154ba319b5SDimitry Andric   IO.mapRequired("Flags", Symbol.Hdr.Flags);
4164ba319b5SDimitry Andric   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
4174ba319b5SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
4184ba319b5SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
419f9448bf3SDimitry Andric }
420f9448bf3SDimitry Andric 
map(IO & IO)421f9448bf3SDimitry Andric template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
422edd7eaddSDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
423edd7eaddSDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
424f9448bf3SDimitry Andric   IO.mapRequired("CodeSize", Symbol.CodeSize);
425edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
426edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
427f9448bf3SDimitry Andric   IO.mapRequired("BlockName", Symbol.Name);
428f9448bf3SDimitry Andric }
429f9448bf3SDimitry Andric 
map(IO & IO)430f9448bf3SDimitry Andric template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
431edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
432edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
433f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
434f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
435f9448bf3SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
436f9448bf3SDimitry Andric }
437f9448bf3SDimitry Andric 
map(IO & IO)438f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
439f9448bf3SDimitry Andric   IO.mapRequired("Signature", Symbol.Signature);
440f9448bf3SDimitry Andric   IO.mapRequired("ObjectName", Symbol.Name);
441f9448bf3SDimitry Andric }
442f9448bf3SDimitry Andric 
map(IO & IO)443f9448bf3SDimitry Andric template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
444f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
445f9448bf3SDimitry Andric   IO.mapRequired("Machine", Symbol.Machine);
446f9448bf3SDimitry Andric   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
447f9448bf3SDimitry Andric   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
448f9448bf3SDimitry Andric   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
449f9448bf3SDimitry Andric   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
450f9448bf3SDimitry Andric   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
451f9448bf3SDimitry Andric   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
452f9448bf3SDimitry Andric   IO.mapRequired("Version", Symbol.Version);
453f9448bf3SDimitry Andric }
454f9448bf3SDimitry Andric 
map(IO & IO)455f9448bf3SDimitry Andric template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
456f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
457f9448bf3SDimitry Andric   IO.mapRequired("Machine", Symbol.Machine);
458f9448bf3SDimitry Andric   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
459f9448bf3SDimitry Andric   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
460f9448bf3SDimitry Andric   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
461f9448bf3SDimitry Andric   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
462f9448bf3SDimitry Andric   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
463f9448bf3SDimitry Andric   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
464f9448bf3SDimitry Andric   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
465f9448bf3SDimitry Andric   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
466f9448bf3SDimitry Andric   IO.mapRequired("Version", Symbol.Version);
467f9448bf3SDimitry Andric }
468f9448bf3SDimitry Andric 
map(IO & IO)469f9448bf3SDimitry Andric template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
470f9448bf3SDimitry Andric   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
471f9448bf3SDimitry Andric   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
472f9448bf3SDimitry Andric   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
473f9448bf3SDimitry Andric   IO.mapRequired("BytesOfCalleeSavedRegisters",
474f9448bf3SDimitry Andric                  Symbol.BytesOfCalleeSavedRegisters);
475f9448bf3SDimitry Andric   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
476f9448bf3SDimitry Andric   IO.mapRequired("SectionIdOfExceptionHandler",
477f9448bf3SDimitry Andric                  Symbol.SectionIdOfExceptionHandler);
478f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
479f9448bf3SDimitry Andric }
480f9448bf3SDimitry Andric 
map(IO & IO)481f9448bf3SDimitry Andric template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
482edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
483edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
484f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
485f9448bf3SDimitry Andric }
486f9448bf3SDimitry Andric 
map(IO & IO)487f9448bf3SDimitry Andric template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
488f9448bf3SDimitry Andric   IO.mapRequired("Index", Symbol.Index);
489f9448bf3SDimitry Andric   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
490f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
491f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
492f9448bf3SDimitry Andric }
493f9448bf3SDimitry Andric 
map(IO & IO)494f9448bf3SDimitry Andric template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
495edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
496edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
497f9448bf3SDimitry Andric   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
498f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
499f9448bf3SDimitry Andric }
500f9448bf3SDimitry Andric 
map(IO & IO)501f9448bf3SDimitry Andric template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
502f9448bf3SDimitry Andric   IO.mapRequired("Register", Symbol.Register);
503f9448bf3SDimitry Andric   IO.mapRequired("CookieKind", Symbol.CookieKind);
504f9448bf3SDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
505f9448bf3SDimitry Andric }
506f9448bf3SDimitry Andric 
map(IO & IO)507f9448bf3SDimitry Andric template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
508f9448bf3SDimitry Andric   IO.mapRequired("FuncID", Symbol.Indices);
509f9448bf3SDimitry Andric }
510f9448bf3SDimitry Andric 
map(IO & IO)511f9448bf3SDimitry Andric template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
512f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
513f9448bf3SDimitry Andric   IO.mapRequired("UDTName", Symbol.Name);
514f9448bf3SDimitry Andric }
515f9448bf3SDimitry Andric 
map(IO & IO)516f9448bf3SDimitry Andric template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
517f9448bf3SDimitry Andric   IO.mapRequired("BuildId", Symbol.BuildId);
518f9448bf3SDimitry Andric }
519f9448bf3SDimitry Andric 
map(IO & IO)520f9448bf3SDimitry Andric template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
521f9448bf3SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
522f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
523f9448bf3SDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
524f9448bf3SDimitry Andric }
525f9448bf3SDimitry Andric 
map(IO & IO)526f9448bf3SDimitry Andric template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
527f9448bf3SDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
528f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
529f9448bf3SDimitry Andric   IO.mapRequired("Register", Symbol.Register);
530f9448bf3SDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
531f9448bf3SDimitry Andric }
532f9448bf3SDimitry Andric 
map(IO & IO)533f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
534f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
535f9448bf3SDimitry Andric   IO.mapRequired("Value", Symbol.Value);
536f9448bf3SDimitry Andric   IO.mapRequired("Name", Symbol.Name);
537f9448bf3SDimitry Andric }
538f9448bf3SDimitry Andric 
map(IO & IO)539f9448bf3SDimitry Andric template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
540f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
541edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
542edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
543f9448bf3SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
544f9448bf3SDimitry Andric }
545f9448bf3SDimitry Andric 
map(IO & IO)546f9448bf3SDimitry Andric template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
547f9448bf3SDimitry Andric   IO.mapRequired("Type", Symbol.Type);
548edd7eaddSDimitry Andric   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
549edd7eaddSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
550f9448bf3SDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
551f9448bf3SDimitry Andric }
552a580b014SDimitry Andric 
map(IO & IO)5534ba319b5SDimitry Andric template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
5544ba319b5SDimitry Andric   IO.mapRequired("Namespace", Symbol.Name);
5554ba319b5SDimitry Andric }
5564ba319b5SDimitry Andric 
557a580b014SDimitry Andric } // end namespace detail
558a580b014SDimitry Andric } // end namespace CodeViewYAML
559a580b014SDimitry Andric } // end namespace llvm
560f9448bf3SDimitry Andric 
toCodeViewSymbol(BumpPtrAllocator & Allocator,CodeViewContainer Container) const561f9448bf3SDimitry Andric CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
5626d97bb29SDimitry Andric     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
5636d97bb29SDimitry Andric   return Symbol->toCodeViewSymbol(Allocator, Container);
564f9448bf3SDimitry Andric }
565f9448bf3SDimitry Andric 
566f9448bf3SDimitry Andric namespace llvm {
567f9448bf3SDimitry Andric namespace yaml {
568a580b014SDimitry Andric 
569f9448bf3SDimitry Andric template <> struct MappingTraits<SymbolRecordBase> {
mappingllvm::yaml::MappingTraits570f9448bf3SDimitry Andric   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
571f9448bf3SDimitry Andric };
572a580b014SDimitry Andric 
573a580b014SDimitry Andric } // end namespace yaml
574a580b014SDimitry Andric } // end namespace llvm
575f9448bf3SDimitry Andric 
576f9448bf3SDimitry Andric template <typename SymbolType>
577f9448bf3SDimitry Andric static inline Expected<CodeViewYAML::SymbolRecord>
fromCodeViewSymbolImpl(CVSymbol Symbol)578f9448bf3SDimitry Andric fromCodeViewSymbolImpl(CVSymbol Symbol) {
579f9448bf3SDimitry Andric   CodeViewYAML::SymbolRecord Result;
580f9448bf3SDimitry Andric 
58124d58133SDimitry Andric   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
582f9448bf3SDimitry Andric   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
583f9448bf3SDimitry Andric     return std::move(EC);
584f9448bf3SDimitry Andric   Result.Symbol = Impl;
585f9448bf3SDimitry Andric   return Result;
586f9448bf3SDimitry Andric }
587f9448bf3SDimitry Andric 
588f9448bf3SDimitry Andric Expected<CodeViewYAML::SymbolRecord>
fromCodeViewSymbol(CVSymbol Symbol)589f9448bf3SDimitry Andric CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
590f9448bf3SDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
591f9448bf3SDimitry Andric   case EnumName:                                                               \
59224d58133SDimitry Andric     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
593f9448bf3SDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
594f9448bf3SDimitry Andric   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
595f9448bf3SDimitry Andric   switch (Symbol.kind()) {
596f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
59724d58133SDimitry Andric   default:
59824d58133SDimitry Andric     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
599f9448bf3SDimitry Andric   }
600f9448bf3SDimitry Andric   return make_error<CodeViewError>(cv_error_code::corrupt_record);
601f9448bf3SDimitry Andric }
602f9448bf3SDimitry Andric 
603f9448bf3SDimitry Andric template <typename ConcreteType>
mapSymbolRecordImpl(IO & IO,const char * Class,SymbolKind Kind,CodeViewYAML::SymbolRecord & Obj)604f9448bf3SDimitry Andric static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
605f9448bf3SDimitry Andric                                 CodeViewYAML::SymbolRecord &Obj) {
606f9448bf3SDimitry Andric   if (!IO.outputting())
60724d58133SDimitry Andric     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
608f9448bf3SDimitry Andric 
609f9448bf3SDimitry Andric   IO.mapRequired(Class, *Obj.Symbol);
610f9448bf3SDimitry Andric }
611f9448bf3SDimitry Andric 
mapping(IO & IO,CodeViewYAML::SymbolRecord & Obj)612f9448bf3SDimitry Andric void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
613f9448bf3SDimitry Andric     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
614f9448bf3SDimitry Andric   SymbolKind Kind;
615f9448bf3SDimitry Andric   if (IO.outputting())
616f9448bf3SDimitry Andric     Kind = Obj.Symbol->Kind;
617f9448bf3SDimitry Andric   IO.mapRequired("Kind", Kind);
618f9448bf3SDimitry Andric 
619f9448bf3SDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
620f9448bf3SDimitry Andric   case EnumName:                                                               \
62124d58133SDimitry Andric     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
62224d58133SDimitry Andric                                                      Obj);                     \
623f9448bf3SDimitry Andric     break;
624f9448bf3SDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
625f9448bf3SDimitry Andric   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
626f9448bf3SDimitry Andric   switch (Kind) {
627f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
62824d58133SDimitry Andric   default:
62924d58133SDimitry Andric     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
630f9448bf3SDimitry Andric   }
631f9448bf3SDimitry Andric }
632