xref: /src/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1f382538dSDimitry Andric //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2f382538dSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f382538dSDimitry Andric //
7f382538dSDimitry Andric //===----------------------------------------------------------------------===//
8f382538dSDimitry Andric //
9f382538dSDimitry Andric // This file defines classes for handling the YAML representation of CodeView
10f382538dSDimitry Andric // Debug Info.
11f382538dSDimitry Andric //
12f382538dSDimitry Andric //===----------------------------------------------------------------------===//
13f382538dSDimitry Andric 
14f382538dSDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
159df3605dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
169df3605dSDimitry Andric #include "llvm/ADT/StringRef.h"
179df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
18f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
19f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/EnumTables.h"
209df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
21f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
229df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
23f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
249df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
259df3605dSDimitry Andric #include "llvm/ObjectYAML/YAML.h"
269df3605dSDimitry Andric #include "llvm/Support/Allocator.h"
279df3605dSDimitry Andric #include "llvm/Support/Error.h"
28145449b1SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
299df3605dSDimitry Andric #include "llvm/Support/YAMLTraits.h"
309df3605dSDimitry Andric #include <algorithm>
319df3605dSDimitry Andric #include <cstdint>
329df3605dSDimitry Andric #include <cstring>
33e3b55780SDimitry Andric #include <optional>
349df3605dSDimitry Andric #include <string>
359df3605dSDimitry Andric #include <vector>
36f382538dSDimitry Andric 
37f382538dSDimitry Andric using namespace llvm;
38f382538dSDimitry Andric using namespace llvm::codeview;
39f382538dSDimitry Andric using namespace llvm::CodeViewYAML;
40f382538dSDimitry Andric using namespace llvm::CodeViewYAML::detail;
41f382538dSDimitry Andric using namespace llvm::yaml;
42f382538dSDimitry Andric 
43f382538dSDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)44eb11fae6SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
45f382538dSDimitry Andric 
46f382538dSDimitry Andric // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
47044eb2f6SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
48044eb2f6SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
49f382538dSDimitry Andric 
50f382538dSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
517c7aba6eSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
52f382538dSDimitry Andric 
53f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
54f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
55f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
5608bbd35aSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
57f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
58f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
59f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
60f382538dSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
61f382538dSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
62f382538dSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
63f382538dSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
64b1c73532SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(JumpTableEntrySize)
65f382538dSDimitry Andric 
669df3605dSDimitry Andric LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
677ab83427SDimitry Andric 
68044eb2f6SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
697ab83427SDimitry Andric 
707ab83427SDimitry Andric StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
717ab83427SDimitry Andric   return ScalarTraits<StringRef>::input(S, V, T.value);
727ab83427SDimitry Andric }
739df3605dSDimitry Andric 
output(const TypeName & T,void * V,raw_ostream & R)747ab83427SDimitry Andric void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
759df3605dSDimitry Andric                                     raw_ostream &R) {
767ab83427SDimitry Andric   ScalarTraits<StringRef>::output(T.value, V, R);
777ab83427SDimitry Andric }
787ab83427SDimitry Andric 
enumeration(IO & io,SymbolKind & Value)79f382538dSDimitry Andric void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
80f382538dSDimitry Andric                                                       SymbolKind &Value) {
81f382538dSDimitry Andric   auto SymbolNames = getSymbolTypeNames();
82f382538dSDimitry Andric   for (const auto &E : SymbolNames)
83f382538dSDimitry Andric     io.enumCase(Value, E.Name.str().c_str(), E.Value);
84f382538dSDimitry Andric }
85f382538dSDimitry Andric 
bitset(IO & io,CompileSym2Flags & Flags)86f382538dSDimitry Andric void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
87f382538dSDimitry Andric                                                   CompileSym2Flags &Flags) {
88f382538dSDimitry Andric   auto FlagNames = getCompileSym2FlagNames();
89f382538dSDimitry Andric   for (const auto &E : FlagNames) {
90f382538dSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
91f382538dSDimitry Andric                   static_cast<CompileSym2Flags>(E.Value));
92f382538dSDimitry Andric   }
93f382538dSDimitry Andric }
94f382538dSDimitry Andric 
bitset(IO & io,CompileSym3Flags & Flags)95f382538dSDimitry Andric void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
96f382538dSDimitry Andric                                                   CompileSym3Flags &Flags) {
97f382538dSDimitry Andric   auto FlagNames = getCompileSym3FlagNames();
98f382538dSDimitry Andric   for (const auto &E : FlagNames) {
99f382538dSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
100f382538dSDimitry Andric                   static_cast<CompileSym3Flags>(E.Value));
101f382538dSDimitry Andric   }
102f382538dSDimitry Andric }
103f382538dSDimitry Andric 
bitset(IO & io,ExportFlags & Flags)104f382538dSDimitry Andric void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
105f382538dSDimitry Andric   auto FlagNames = getExportSymFlagNames();
106f382538dSDimitry Andric   for (const auto &E : FlagNames) {
107f382538dSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
108f382538dSDimitry Andric                   static_cast<ExportFlags>(E.Value));
109f382538dSDimitry Andric   }
110f382538dSDimitry Andric }
111f382538dSDimitry Andric 
bitset(IO & io,PublicSymFlags & Flags)11208bbd35aSDimitry Andric void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
113d8e91e46SDimitry Andric   auto FlagNames = getPublicSymFlagNames();
11408bbd35aSDimitry Andric   for (const auto &E : FlagNames) {
11508bbd35aSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
11608bbd35aSDimitry Andric                   static_cast<PublicSymFlags>(E.Value));
11708bbd35aSDimitry Andric   }
11808bbd35aSDimitry Andric }
11908bbd35aSDimitry Andric 
bitset(IO & io,LocalSymFlags & Flags)120f382538dSDimitry Andric void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
121f382538dSDimitry Andric   auto FlagNames = getLocalFlagNames();
122f382538dSDimitry Andric   for (const auto &E : FlagNames) {
123f382538dSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
124f382538dSDimitry Andric                   static_cast<LocalSymFlags>(E.Value));
125f382538dSDimitry Andric   }
126f382538dSDimitry Andric }
127f382538dSDimitry Andric 
bitset(IO & io,ProcSymFlags & Flags)128f382538dSDimitry Andric void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
129f382538dSDimitry Andric   auto FlagNames = getProcSymFlagNames();
130f382538dSDimitry Andric   for (const auto &E : FlagNames) {
131f382538dSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
132f382538dSDimitry Andric                   static_cast<ProcSymFlags>(E.Value));
133f382538dSDimitry Andric   }
134f382538dSDimitry Andric }
135f382538dSDimitry Andric 
bitset(IO & io,FrameProcedureOptions & Flags)136f382538dSDimitry Andric void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
137f382538dSDimitry Andric     IO &io, FrameProcedureOptions &Flags) {
138f382538dSDimitry Andric   auto FlagNames = getFrameProcSymFlagNames();
139f382538dSDimitry Andric   for (const auto &E : FlagNames) {
140f382538dSDimitry Andric     io.bitSetCase(Flags, E.Name.str().c_str(),
141f382538dSDimitry Andric                   static_cast<FrameProcedureOptions>(E.Value));
142f382538dSDimitry Andric   }
143f382538dSDimitry Andric }
144f382538dSDimitry Andric 
enumeration(IO & io,CPUType & Cpu)145f382538dSDimitry Andric void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
146f382538dSDimitry Andric   auto CpuNames = getCPUTypeNames();
147f382538dSDimitry Andric   for (const auto &E : CpuNames) {
148f382538dSDimitry Andric     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
149f382538dSDimitry Andric   }
150f382538dSDimitry Andric }
151f382538dSDimitry Andric 
enumeration(IO & io,RegisterId & Reg)152f382538dSDimitry Andric void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
153b60736ecSDimitry Andric   const auto *Header = static_cast<COFF::header *>(io.getContext());
154b60736ecSDimitry Andric   assert(Header && "The IO context is not initialized");
155b60736ecSDimitry Andric 
156e3b55780SDimitry Andric   std::optional<CPUType> CpuType;
157b60736ecSDimitry Andric   ArrayRef<EnumEntry<uint16_t>> RegNames;
158b60736ecSDimitry Andric 
159b60736ecSDimitry Andric   switch (Header->Machine) {
160b60736ecSDimitry Andric   case COFF::IMAGE_FILE_MACHINE_I386:
161b60736ecSDimitry Andric     CpuType = CPUType::Pentium3;
162b60736ecSDimitry Andric     break;
163b60736ecSDimitry Andric   case COFF::IMAGE_FILE_MACHINE_AMD64:
164b60736ecSDimitry Andric     CpuType = CPUType::X64;
165b60736ecSDimitry Andric     break;
166b60736ecSDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARMNT:
167b60736ecSDimitry Andric     CpuType = CPUType::ARMNT;
168b60736ecSDimitry Andric     break;
169b60736ecSDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARM64:
170e3b55780SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
1717fa27ce4SDimitry Andric   case COFF::IMAGE_FILE_MACHINE_ARM64X:
172b60736ecSDimitry Andric     CpuType = CPUType::ARM64;
173b60736ecSDimitry Andric     break;
174b60736ecSDimitry Andric   }
175b60736ecSDimitry Andric 
176b60736ecSDimitry Andric   if (CpuType)
177b60736ecSDimitry Andric     RegNames = getRegisterNames(*CpuType);
178b60736ecSDimitry Andric 
179f382538dSDimitry Andric   for (const auto &E : RegNames) {
180f382538dSDimitry Andric     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
181f382538dSDimitry Andric   }
182f382538dSDimitry Andric   io.enumFallback<Hex16>(Reg);
183f382538dSDimitry Andric }
184f382538dSDimitry Andric 
enumeration(IO & io,TrampolineType & Tramp)185f382538dSDimitry Andric void ScalarEnumerationTraits<TrampolineType>::enumeration(
186f382538dSDimitry Andric     IO &io, TrampolineType &Tramp) {
187f382538dSDimitry Andric   auto TrampNames = getTrampolineNames();
188f382538dSDimitry Andric   for (const auto &E : TrampNames) {
189f382538dSDimitry Andric     io.enumCase(Tramp, E.Name.str().c_str(),
190f382538dSDimitry Andric                 static_cast<TrampolineType>(E.Value));
191f382538dSDimitry Andric   }
192f382538dSDimitry Andric }
193f382538dSDimitry Andric 
enumeration(IO & io,ThunkOrdinal & Ord)194f382538dSDimitry Andric void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
195f382538dSDimitry Andric                                                         ThunkOrdinal &Ord) {
196f382538dSDimitry Andric   auto ThunkNames = getThunkOrdinalNames();
197f382538dSDimitry Andric   for (const auto &E : ThunkNames) {
198f382538dSDimitry Andric     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
199f382538dSDimitry Andric   }
200f382538dSDimitry Andric }
201f382538dSDimitry Andric 
enumeration(IO & io,FrameCookieKind & FC)2027c7aba6eSDimitry Andric void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
2037c7aba6eSDimitry Andric     IO &io, FrameCookieKind &FC) {
2047c7aba6eSDimitry Andric   auto ThunkNames = getFrameCookieKindNames();
2057c7aba6eSDimitry Andric   for (const auto &E : ThunkNames) {
2067c7aba6eSDimitry Andric     io.enumCase(FC, E.Name.str().c_str(),
2077c7aba6eSDimitry Andric                 static_cast<FrameCookieKind>(E.Value));
2087c7aba6eSDimitry Andric   }
2097c7aba6eSDimitry Andric }
2107c7aba6eSDimitry Andric 
enumeration(IO & io,JumpTableEntrySize & FC)211b1c73532SDimitry Andric void ScalarEnumerationTraits<JumpTableEntrySize>::enumeration(
212b1c73532SDimitry Andric     IO &io, JumpTableEntrySize &FC) {
213b1c73532SDimitry Andric   auto ThunkNames = getJumpTableEntrySizeNames();
214b1c73532SDimitry Andric   for (const auto &E : ThunkNames) {
215b1c73532SDimitry Andric     io.enumCase(FC, E.Name.str().c_str(),
216b1c73532SDimitry Andric                 static_cast<JumpTableEntrySize>(E.Value));
217b1c73532SDimitry Andric   }
218b1c73532SDimitry Andric }
219b1c73532SDimitry Andric 
220f382538dSDimitry Andric namespace llvm {
221eb11fae6SDimitry Andric namespace yaml {
222eb11fae6SDimitry Andric template <> struct MappingTraits<LocalVariableAddrRange> {
mappingllvm::yaml::MappingTraits223eb11fae6SDimitry Andric   static void mapping(IO &io, LocalVariableAddrRange &Range) {
224eb11fae6SDimitry Andric     io.mapRequired("OffsetStart", Range.OffsetStart);
225eb11fae6SDimitry Andric     io.mapRequired("ISectStart", Range.ISectStart);
226eb11fae6SDimitry Andric     io.mapRequired("Range", Range.Range);
227eb11fae6SDimitry Andric   }
228eb11fae6SDimitry Andric };
229eb11fae6SDimitry Andric template <> struct MappingTraits<LocalVariableAddrGap> {
mappingllvm::yaml::MappingTraits230eb11fae6SDimitry Andric   static void mapping(IO &io, LocalVariableAddrGap &Gap) {
231eb11fae6SDimitry Andric     io.mapRequired("GapStartOffset", Gap.GapStartOffset);
232eb11fae6SDimitry Andric     io.mapRequired("Range", Gap.Range);
233eb11fae6SDimitry Andric   }
234eb11fae6SDimitry Andric };
235eb11fae6SDimitry Andric } // namespace yaml
236eb11fae6SDimitry Andric } // namespace llvm
237eb11fae6SDimitry Andric 
238eb11fae6SDimitry Andric namespace llvm {
239f382538dSDimitry Andric namespace CodeViewYAML {
240f382538dSDimitry Andric namespace detail {
241f382538dSDimitry Andric 
242f382538dSDimitry Andric struct SymbolRecordBase {
243f382538dSDimitry Andric   codeview::SymbolKind Kind;
244f382538dSDimitry Andric 
SymbolRecordBasellvm::CodeViewYAML::detail::SymbolRecordBase2459df3605dSDimitry Andric   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
2469df3605dSDimitry Andric   virtual ~SymbolRecordBase() = default;
2479df3605dSDimitry Andric 
248f382538dSDimitry Andric   virtual void map(yaml::IO &io) = 0;
249f382538dSDimitry Andric   virtual codeview::CVSymbol
250d288ef4cSDimitry Andric   toCodeViewSymbol(BumpPtrAllocator &Allocator,
251d288ef4cSDimitry Andric                    CodeViewContainer Container) const = 0;
252f382538dSDimitry Andric   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
253f382538dSDimitry Andric };
254f382538dSDimitry Andric 
255f382538dSDimitry Andric template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
SymbolRecordImplllvm::CodeViewYAML::detail::SymbolRecordImpl256f382538dSDimitry Andric   explicit SymbolRecordImpl(codeview::SymbolKind K)
257f382538dSDimitry Andric       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
258f382538dSDimitry Andric 
259f382538dSDimitry Andric   void map(yaml::IO &io) override;
260f382538dSDimitry Andric 
261f382538dSDimitry Andric   codeview::CVSymbol
toCodeViewSymbolllvm::CodeViewYAML::detail::SymbolRecordImpl262d288ef4cSDimitry Andric   toCodeViewSymbol(BumpPtrAllocator &Allocator,
263d288ef4cSDimitry Andric                    CodeViewContainer Container) const override {
264d288ef4cSDimitry Andric     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
265f382538dSDimitry Andric   }
2669df3605dSDimitry Andric 
fromCodeViewSymbolllvm::CodeViewYAML::detail::SymbolRecordImpl267f382538dSDimitry Andric   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
268f382538dSDimitry Andric     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
269f382538dSDimitry Andric   }
270f382538dSDimitry Andric 
271f382538dSDimitry Andric   mutable T Symbol;
272f382538dSDimitry Andric };
273f382538dSDimitry Andric 
2747c7aba6eSDimitry Andric struct UnknownSymbolRecord : public SymbolRecordBase {
UnknownSymbolRecordllvm::CodeViewYAML::detail::UnknownSymbolRecord2757c7aba6eSDimitry Andric   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
2767c7aba6eSDimitry Andric 
2777c7aba6eSDimitry Andric   void map(yaml::IO &io) override;
2787c7aba6eSDimitry Andric 
toCodeViewSymbolllvm::CodeViewYAML::detail::UnknownSymbolRecord2797c7aba6eSDimitry Andric   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
2807c7aba6eSDimitry Andric                             CodeViewContainer Container) const override {
2817c7aba6eSDimitry Andric     RecordPrefix Prefix;
2827c7aba6eSDimitry Andric     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
2837c7aba6eSDimitry Andric     Prefix.RecordKind = Kind;
2847c7aba6eSDimitry Andric     Prefix.RecordLen = TotalLen - 2;
2857c7aba6eSDimitry Andric     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
2867c7aba6eSDimitry Andric     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
2877c7aba6eSDimitry Andric     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
288e6d15924SDimitry Andric     return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
2897c7aba6eSDimitry Andric   }
2909df3605dSDimitry Andric 
fromCodeViewSymbolllvm::CodeViewYAML::detail::UnknownSymbolRecord2917c7aba6eSDimitry Andric   Error fromCodeViewSymbol(CVSymbol CVS) override {
2927c7aba6eSDimitry Andric     this->Kind = CVS.kind();
2937c7aba6eSDimitry Andric     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
2947c7aba6eSDimitry Andric     return Error::success();
2957c7aba6eSDimitry Andric   }
2967c7aba6eSDimitry Andric 
2977c7aba6eSDimitry Andric   std::vector<uint8_t> Data;
2987c7aba6eSDimitry Andric };
2997c7aba6eSDimitry Andric 
map(IO & IO)300f382538dSDimitry Andric template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
301f382538dSDimitry Andric 
map(yaml::IO & io)3027c7aba6eSDimitry Andric void UnknownSymbolRecord::map(yaml::IO &io) {
3037c7aba6eSDimitry Andric   yaml::BinaryRef Binary;
3047c7aba6eSDimitry Andric   if (io.outputting())
3057c7aba6eSDimitry Andric     Binary = yaml::BinaryRef(Data);
3067c7aba6eSDimitry Andric   io.mapRequired("Data", Binary);
3077c7aba6eSDimitry Andric   if (!io.outputting()) {
3087c7aba6eSDimitry Andric     std::string Str;
3097c7aba6eSDimitry Andric     raw_string_ostream OS(Str);
3107c7aba6eSDimitry Andric     Binary.writeAsBinary(OS);
3117c7aba6eSDimitry Andric     OS.flush();
3127c7aba6eSDimitry Andric     Data.assign(Str.begin(), Str.end());
3137c7aba6eSDimitry Andric   }
3147c7aba6eSDimitry Andric }
3157c7aba6eSDimitry Andric 
map(IO & IO)316f382538dSDimitry Andric template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
317f382538dSDimitry Andric   IO.mapRequired("Parent", Symbol.Parent);
318f382538dSDimitry Andric   IO.mapRequired("End", Symbol.End);
319f382538dSDimitry Andric   IO.mapRequired("Next", Symbol.Next);
320f382538dSDimitry Andric   IO.mapRequired("Off", Symbol.Offset);
321f382538dSDimitry Andric   IO.mapRequired("Seg", Symbol.Segment);
322f382538dSDimitry Andric   IO.mapRequired("Len", Symbol.Length);
323f382538dSDimitry Andric   IO.mapRequired("Ordinal", Symbol.Thunk);
324f382538dSDimitry Andric }
325f382538dSDimitry Andric 
map(IO & IO)326f382538dSDimitry Andric template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
327f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
328f382538dSDimitry Andric   IO.mapRequired("Size", Symbol.Size);
329f382538dSDimitry Andric   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
330f382538dSDimitry Andric   IO.mapRequired("TargetOff", Symbol.TargetOffset);
331f382538dSDimitry Andric   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
332f382538dSDimitry Andric   IO.mapRequired("TargetSection", Symbol.TargetSection);
333f382538dSDimitry Andric }
334f382538dSDimitry Andric 
map(IO & IO)335f382538dSDimitry Andric template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
336f382538dSDimitry Andric   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
337f382538dSDimitry Andric   IO.mapRequired("Alignment", Symbol.Alignment);
338f382538dSDimitry Andric   IO.mapRequired("Rva", Symbol.Rva);
339f382538dSDimitry Andric   IO.mapRequired("Length", Symbol.Length);
340f382538dSDimitry Andric   IO.mapRequired("Characteristics", Symbol.Characteristics);
341f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
342f382538dSDimitry Andric }
343f382538dSDimitry Andric 
map(IO & IO)344f382538dSDimitry Andric template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
345f382538dSDimitry Andric   IO.mapRequired("Size", Symbol.Size);
346f382538dSDimitry Andric   IO.mapRequired("Characteristics", Symbol.Characteristics);
347f382538dSDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
348f382538dSDimitry Andric   IO.mapRequired("Segment", Symbol.Segment);
349f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
350f382538dSDimitry Andric }
351f382538dSDimitry Andric 
map(IO & IO)352f382538dSDimitry Andric template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
353f382538dSDimitry Andric   IO.mapRequired("Ordinal", Symbol.Ordinal);
354f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
355f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
356f382538dSDimitry Andric }
357f382538dSDimitry Andric 
map(IO & IO)358f382538dSDimitry Andric template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
35908bbd35aSDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
36008bbd35aSDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
36108bbd35aSDimitry Andric   IO.mapOptional("PtrNext", Symbol.Next, 0U);
362f382538dSDimitry Andric   IO.mapRequired("CodeSize", Symbol.CodeSize);
363f382538dSDimitry Andric   IO.mapRequired("DbgStart", Symbol.DbgStart);
364f382538dSDimitry Andric   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
365f382538dSDimitry Andric   IO.mapRequired("FunctionType", Symbol.FunctionType);
36608bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
36708bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
368f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
369f382538dSDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
370f382538dSDimitry Andric }
371f382538dSDimitry Andric 
map(IO & IO)372f382538dSDimitry Andric template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
373f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Index);
374f382538dSDimitry Andric   IO.mapRequired("Seg", Symbol.Register);
375f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
376f382538dSDimitry Andric }
377f382538dSDimitry Andric 
map(IO & IO)378f382538dSDimitry Andric template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
37908bbd35aSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
38008bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.Offset, 0U);
38108bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
382f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
383f382538dSDimitry Andric }
384f382538dSDimitry Andric 
map(IO & IO)385f382538dSDimitry Andric template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
386f382538dSDimitry Andric   IO.mapRequired("SumName", Symbol.SumName);
387f382538dSDimitry Andric   IO.mapRequired("SymOffset", Symbol.SymOffset);
388f382538dSDimitry Andric   IO.mapRequired("Mod", Symbol.Module);
389f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
390f382538dSDimitry Andric }
391f382538dSDimitry Andric 
map(IO & IO)392f382538dSDimitry Andric template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
393f382538dSDimitry Andric   IO.mapRequired("Entries", Symbol.Fields);
394f382538dSDimitry Andric }
395f382538dSDimitry Andric 
map(IO & IO)396f382538dSDimitry Andric template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
39708bbd35aSDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
39808bbd35aSDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
399f382538dSDimitry Andric   IO.mapRequired("Inlinee", Symbol.Inlinee);
400f382538dSDimitry Andric   // TODO: The binary annotations
401f382538dSDimitry Andric }
402f382538dSDimitry Andric 
map(IO & IO)403f382538dSDimitry Andric template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
404f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
405f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
4067ab83427SDimitry Andric 
407f382538dSDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
408f382538dSDimitry Andric }
409f382538dSDimitry Andric 
map(IO & IO)410f382538dSDimitry Andric template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
411eb11fae6SDimitry Andric   IO.mapRequired("Program", Symbol.Program);
412eb11fae6SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
413eb11fae6SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
414f382538dSDimitry Andric }
415f382538dSDimitry Andric 
map(IO & IO)416f382538dSDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
417eb11fae6SDimitry Andric   IO.mapRequired("Program", Symbol.Program);
418eb11fae6SDimitry Andric   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
419eb11fae6SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
420eb11fae6SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
421f382538dSDimitry Andric }
422f382538dSDimitry Andric 
map(IO & IO)423f382538dSDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
424eb11fae6SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
425eb11fae6SDimitry Andric   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
426eb11fae6SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
427eb11fae6SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
428f382538dSDimitry Andric }
429f382538dSDimitry Andric 
map(IO & IO)430f382538dSDimitry Andric template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
4311d5ae102SDimitry Andric   IO.mapRequired("Offset", Symbol.Hdr.Offset);
432eb11fae6SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
433eb11fae6SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
434f382538dSDimitry Andric }
435f382538dSDimitry Andric 
map(IO & IO)436f382538dSDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
437eb11fae6SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
438eb11fae6SDimitry Andric   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
439eb11fae6SDimitry Andric   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
440eb11fae6SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
441eb11fae6SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
442f382538dSDimitry Andric }
443f382538dSDimitry Andric 
444f382538dSDimitry Andric template <>
map(IO & IO)445f382538dSDimitry Andric void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
446eb11fae6SDimitry Andric   IO.mapRequired("Register", Symbol.Offset);
447f382538dSDimitry Andric }
448f382538dSDimitry Andric 
map(IO & IO)449f382538dSDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
450eb11fae6SDimitry Andric   IO.mapRequired("Register", Symbol.Hdr.Register);
451eb11fae6SDimitry Andric   IO.mapRequired("Flags", Symbol.Hdr.Flags);
452eb11fae6SDimitry Andric   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
453eb11fae6SDimitry Andric   IO.mapRequired("Range", Symbol.Range);
454eb11fae6SDimitry Andric   IO.mapRequired("Gaps", Symbol.Gaps);
455f382538dSDimitry Andric }
456f382538dSDimitry Andric 
map(IO & IO)457f382538dSDimitry Andric template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
45808bbd35aSDimitry Andric   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
45908bbd35aSDimitry Andric   IO.mapOptional("PtrEnd", Symbol.End, 0U);
460f382538dSDimitry Andric   IO.mapRequired("CodeSize", Symbol.CodeSize);
46108bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
46208bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
463f382538dSDimitry Andric   IO.mapRequired("BlockName", Symbol.Name);
464f382538dSDimitry Andric }
465f382538dSDimitry Andric 
map(IO & IO)466f382538dSDimitry Andric template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
46708bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
46808bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
469f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
470f382538dSDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
471f382538dSDimitry Andric }
472f382538dSDimitry Andric 
map(IO & IO)473f382538dSDimitry Andric template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
474f382538dSDimitry Andric   IO.mapRequired("Signature", Symbol.Signature);
475f382538dSDimitry Andric   IO.mapRequired("ObjectName", Symbol.Name);
476f382538dSDimitry Andric }
477f382538dSDimitry Andric 
map(IO & IO)478f382538dSDimitry Andric template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
479f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
480f382538dSDimitry Andric   IO.mapRequired("Machine", Symbol.Machine);
481f382538dSDimitry Andric   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
482f382538dSDimitry Andric   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
483f382538dSDimitry Andric   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
484f382538dSDimitry Andric   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
485f382538dSDimitry Andric   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
486f382538dSDimitry Andric   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
487f382538dSDimitry Andric   IO.mapRequired("Version", Symbol.Version);
488f382538dSDimitry Andric }
489f382538dSDimitry Andric 
map(IO & IO)490f382538dSDimitry Andric template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
491f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
492f382538dSDimitry Andric   IO.mapRequired("Machine", Symbol.Machine);
493f382538dSDimitry Andric   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
494f382538dSDimitry Andric   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
495f382538dSDimitry Andric   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
496f382538dSDimitry Andric   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
497f382538dSDimitry Andric   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
498f382538dSDimitry Andric   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
499f382538dSDimitry Andric   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
500f382538dSDimitry Andric   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
501f382538dSDimitry Andric   IO.mapRequired("Version", Symbol.Version);
502f382538dSDimitry Andric }
503f382538dSDimitry Andric 
map(IO & IO)504f382538dSDimitry Andric template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
505f382538dSDimitry Andric   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
506f382538dSDimitry Andric   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
507f382538dSDimitry Andric   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
508f382538dSDimitry Andric   IO.mapRequired("BytesOfCalleeSavedRegisters",
509f382538dSDimitry Andric                  Symbol.BytesOfCalleeSavedRegisters);
510f382538dSDimitry Andric   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
511f382538dSDimitry Andric   IO.mapRequired("SectionIdOfExceptionHandler",
512f382538dSDimitry Andric                  Symbol.SectionIdOfExceptionHandler);
513f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
514f382538dSDimitry Andric }
515f382538dSDimitry Andric 
map(IO & IO)516f382538dSDimitry Andric template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
51708bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
51808bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
519f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
520f382538dSDimitry Andric }
521f382538dSDimitry Andric 
map(IO & IO)522f382538dSDimitry Andric template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
523f382538dSDimitry Andric   IO.mapRequired("Index", Symbol.Index);
524f382538dSDimitry Andric   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
525f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
526f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
527f382538dSDimitry Andric }
528f382538dSDimitry Andric 
map(IO & IO)529f382538dSDimitry Andric template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
53008bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
53108bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
532f382538dSDimitry Andric   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
533f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
534f382538dSDimitry Andric }
535f382538dSDimitry Andric 
map(IO & IO)536f382538dSDimitry Andric template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
537f382538dSDimitry Andric   IO.mapRequired("Register", Symbol.Register);
538f382538dSDimitry Andric   IO.mapRequired("CookieKind", Symbol.CookieKind);
539f382538dSDimitry Andric   IO.mapRequired("Flags", Symbol.Flags);
540f382538dSDimitry Andric }
541f382538dSDimitry Andric 
map(IO & IO)542f382538dSDimitry Andric template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
543f382538dSDimitry Andric   IO.mapRequired("FuncID", Symbol.Indices);
544f382538dSDimitry Andric }
545f382538dSDimitry Andric 
map(IO & IO)546f382538dSDimitry Andric template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
547f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
548f382538dSDimitry Andric   IO.mapRequired("UDTName", Symbol.Name);
549f382538dSDimitry Andric }
550f382538dSDimitry Andric 
map(IO & IO)551f382538dSDimitry Andric template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
552f382538dSDimitry Andric   IO.mapRequired("BuildId", Symbol.BuildId);
553f382538dSDimitry Andric }
554f382538dSDimitry Andric 
map(IO & IO)555f382538dSDimitry Andric template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
556f382538dSDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
557f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
558f382538dSDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
559f382538dSDimitry Andric }
560f382538dSDimitry Andric 
map(IO & IO)561f382538dSDimitry Andric template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
562f382538dSDimitry Andric   IO.mapRequired("Offset", Symbol.Offset);
563f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
564f382538dSDimitry Andric   IO.mapRequired("Register", Symbol.Register);
565f382538dSDimitry Andric   IO.mapRequired("VarName", Symbol.Name);
566f382538dSDimitry Andric }
567f382538dSDimitry Andric 
map(IO & IO)568f382538dSDimitry Andric template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
569f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
570f382538dSDimitry Andric   IO.mapRequired("Value", Symbol.Value);
571f382538dSDimitry Andric   IO.mapRequired("Name", Symbol.Name);
572f382538dSDimitry Andric }
573f382538dSDimitry Andric 
map(IO & IO)574f382538dSDimitry Andric template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
575f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
57608bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
57708bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
578f382538dSDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
579f382538dSDimitry Andric }
580f382538dSDimitry Andric 
map(IO & IO)581f382538dSDimitry Andric template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
582f382538dSDimitry Andric   IO.mapRequired("Type", Symbol.Type);
58308bbd35aSDimitry Andric   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
58408bbd35aSDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
585f382538dSDimitry Andric   IO.mapRequired("DisplayName", Symbol.Name);
586f382538dSDimitry Andric }
5879df3605dSDimitry Andric 
map(IO & IO)588b7eb8e35SDimitry Andric template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
589b7eb8e35SDimitry Andric   IO.mapRequired("Namespace", Symbol.Name);
590b7eb8e35SDimitry Andric }
591b7eb8e35SDimitry Andric 
map(IO & IO)592e6d15924SDimitry Andric template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
593e6d15924SDimitry Andric   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
594e6d15924SDimitry Andric   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
595e6d15924SDimitry Andric   IO.mapRequired("Strings", Symbol.Strings);
596e6d15924SDimitry Andric }
597e6d15924SDimitry Andric 
map(IO & IO)598b1c73532SDimitry Andric template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) {
599b1c73532SDimitry Andric   IO.mapRequired("BaseOffset", Symbol.BaseOffset);
600b1c73532SDimitry Andric   IO.mapRequired("BaseSegment", Symbol.BaseSegment);
601b1c73532SDimitry Andric   IO.mapRequired("SwitchType", Symbol.SwitchType);
602b1c73532SDimitry Andric   IO.mapRequired("BranchOffset", Symbol.BranchOffset);
603b1c73532SDimitry Andric   IO.mapRequired("TableOffset", Symbol.TableOffset);
604b1c73532SDimitry Andric   IO.mapRequired("BranchSegment", Symbol.BranchSegment);
605b1c73532SDimitry Andric   IO.mapRequired("TableSegment", Symbol.TableSegment);
606b1c73532SDimitry Andric   IO.mapRequired("EntriesCount", Symbol.EntriesCount);
607b1c73532SDimitry Andric }
608b1c73532SDimitry Andric 
6099df3605dSDimitry Andric } // end namespace detail
6109df3605dSDimitry Andric } // end namespace CodeViewYAML
6119df3605dSDimitry Andric } // end namespace llvm
612f382538dSDimitry Andric 
toCodeViewSymbol(BumpPtrAllocator & Allocator,CodeViewContainer Container) const613f382538dSDimitry Andric CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
614d288ef4cSDimitry Andric     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
615d288ef4cSDimitry Andric   return Symbol->toCodeViewSymbol(Allocator, Container);
616f382538dSDimitry Andric }
617f382538dSDimitry Andric 
618f382538dSDimitry Andric namespace llvm {
619f382538dSDimitry Andric namespace yaml {
6209df3605dSDimitry Andric 
621f382538dSDimitry Andric template <> struct MappingTraits<SymbolRecordBase> {
mappingllvm::yaml::MappingTraits622f382538dSDimitry Andric   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
623f382538dSDimitry Andric };
6249df3605dSDimitry Andric 
6259df3605dSDimitry Andric } // end namespace yaml
6269df3605dSDimitry Andric } // end namespace llvm
627f382538dSDimitry Andric 
628f382538dSDimitry Andric template <typename SymbolType>
629f382538dSDimitry Andric static inline Expected<CodeViewYAML::SymbolRecord>
fromCodeViewSymbolImpl(CVSymbol Symbol)630f382538dSDimitry Andric fromCodeViewSymbolImpl(CVSymbol Symbol) {
631f382538dSDimitry Andric   CodeViewYAML::SymbolRecord Result;
632f382538dSDimitry Andric 
6337c7aba6eSDimitry Andric   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
634f382538dSDimitry Andric   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
635f382538dSDimitry Andric     return std::move(EC);
636f382538dSDimitry Andric   Result.Symbol = Impl;
637f382538dSDimitry Andric   return Result;
638f382538dSDimitry Andric }
639f382538dSDimitry Andric 
640f382538dSDimitry Andric Expected<CodeViewYAML::SymbolRecord>
fromCodeViewSymbol(CVSymbol Symbol)641f382538dSDimitry Andric CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
642f382538dSDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
643f382538dSDimitry Andric   case EnumName:                                                               \
6447c7aba6eSDimitry Andric     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
645f382538dSDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
646f382538dSDimitry Andric   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
647f382538dSDimitry Andric   switch (Symbol.kind()) {
648f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
6497c7aba6eSDimitry Andric   default:
6507c7aba6eSDimitry Andric     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
651f382538dSDimitry Andric   }
652f382538dSDimitry Andric   return make_error<CodeViewError>(cv_error_code::corrupt_record);
653f382538dSDimitry Andric }
654f382538dSDimitry Andric 
655f382538dSDimitry Andric template <typename ConcreteType>
mapSymbolRecordImpl(IO & IO,const char * Class,SymbolKind Kind,CodeViewYAML::SymbolRecord & Obj)656f382538dSDimitry Andric static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
657f382538dSDimitry Andric                                 CodeViewYAML::SymbolRecord &Obj) {
658f382538dSDimitry Andric   if (!IO.outputting())
6597c7aba6eSDimitry Andric     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
660f382538dSDimitry Andric 
661f382538dSDimitry Andric   IO.mapRequired(Class, *Obj.Symbol);
662f382538dSDimitry Andric }
663f382538dSDimitry Andric 
mapping(IO & IO,CodeViewYAML::SymbolRecord & Obj)664f382538dSDimitry Andric void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
665f382538dSDimitry Andric     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
666f382538dSDimitry Andric   SymbolKind Kind;
667f382538dSDimitry Andric   if (IO.outputting())
668f382538dSDimitry Andric     Kind = Obj.Symbol->Kind;
669f382538dSDimitry Andric   IO.mapRequired("Kind", Kind);
670f382538dSDimitry Andric 
671f382538dSDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
672f382538dSDimitry Andric   case EnumName:                                                               \
6737c7aba6eSDimitry Andric     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
6747c7aba6eSDimitry Andric                                                      Obj);                     \
675f382538dSDimitry Andric     break;
676f382538dSDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
677f382538dSDimitry Andric   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
678f382538dSDimitry Andric   switch (Kind) {
679f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
6807c7aba6eSDimitry Andric   default:
6817c7aba6eSDimitry Andric     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
682f382538dSDimitry Andric   }
683f382538dSDimitry Andric }
684