]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/ObjectYAML/CodeViewYAMLSymbols.cpp
Vendor import of llvm trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / lib / ObjectYAML / CodeViewYAMLSymbols.cpp
1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines classes for handling the YAML representation of CodeView
11 // Debug Info.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/DebugInfo/CodeView/CodeView.h"
19 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
20 #include "llvm/DebugInfo/CodeView/EnumTables.h"
21 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
22 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
23 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
24 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
25 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
26 #include "llvm/ObjectYAML/YAML.h"
27 #include "llvm/Support/Allocator.h"
28 #include "llvm/Support/Error.h"
29 #include "llvm/Support/YAMLTraits.h"
30 #include <algorithm>
31 #include <cstdint>
32 #include <cstring>
33 #include <string>
34 #include <vector>
35
36 using namespace llvm;
37 using namespace llvm::codeview;
38 using namespace llvm::CodeViewYAML;
39 using namespace llvm::CodeViewYAML::detail;
40 using namespace llvm::yaml;
41
42 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
43 LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
44
45 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
46 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
47 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
48
49 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
50 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
51
52 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
53 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
54 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
55 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
56 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
57 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
58 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
59 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
61 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
62 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
63
64 LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
65
66 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
67
68 StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
69   return ScalarTraits<StringRef>::input(S, V, T.value);
70 }
71
72 void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
73                                     raw_ostream &R) {
74   ScalarTraits<StringRef>::output(T.value, V, R);
75 }
76
77 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
78                                                       SymbolKind &Value) {
79   auto SymbolNames = getSymbolTypeNames();
80   for (const auto &E : SymbolNames)
81     io.enumCase(Value, E.Name.str().c_str(), E.Value);
82 }
83
84 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
85                                                   CompileSym2Flags &Flags) {
86   auto FlagNames = getCompileSym2FlagNames();
87   for (const auto &E : FlagNames) {
88     io.bitSetCase(Flags, E.Name.str().c_str(),
89                   static_cast<CompileSym2Flags>(E.Value));
90   }
91 }
92
93 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
94                                                   CompileSym3Flags &Flags) {
95   auto FlagNames = getCompileSym3FlagNames();
96   for (const auto &E : FlagNames) {
97     io.bitSetCase(Flags, E.Name.str().c_str(),
98                   static_cast<CompileSym3Flags>(E.Value));
99   }
100 }
101
102 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
103   auto FlagNames = getExportSymFlagNames();
104   for (const auto &E : FlagNames) {
105     io.bitSetCase(Flags, E.Name.str().c_str(),
106                   static_cast<ExportFlags>(E.Value));
107   }
108 }
109
110 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
111   auto FlagNames = getPublicSymFlagNames();
112   for (const auto &E : FlagNames) {
113     io.bitSetCase(Flags, E.Name.str().c_str(),
114                   static_cast<PublicSymFlags>(E.Value));
115   }
116 }
117
118 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
119   auto FlagNames = getLocalFlagNames();
120   for (const auto &E : FlagNames) {
121     io.bitSetCase(Flags, E.Name.str().c_str(),
122                   static_cast<LocalSymFlags>(E.Value));
123   }
124 }
125
126 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
127   auto FlagNames = getProcSymFlagNames();
128   for (const auto &E : FlagNames) {
129     io.bitSetCase(Flags, E.Name.str().c_str(),
130                   static_cast<ProcSymFlags>(E.Value));
131   }
132 }
133
134 void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
135     IO &io, FrameProcedureOptions &Flags) {
136   auto FlagNames = getFrameProcSymFlagNames();
137   for (const auto &E : FlagNames) {
138     io.bitSetCase(Flags, E.Name.str().c_str(),
139                   static_cast<FrameProcedureOptions>(E.Value));
140   }
141 }
142
143 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
144   auto CpuNames = getCPUTypeNames();
145   for (const auto &E : CpuNames) {
146     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
147   }
148 }
149
150 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
151   auto RegNames = getRegisterNames();
152   for (const auto &E : RegNames) {
153     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
154   }
155   io.enumFallback<Hex16>(Reg);
156 }
157
158 void ScalarEnumerationTraits<TrampolineType>::enumeration(
159     IO &io, TrampolineType &Tramp) {
160   auto TrampNames = getTrampolineNames();
161   for (const auto &E : TrampNames) {
162     io.enumCase(Tramp, E.Name.str().c_str(),
163                 static_cast<TrampolineType>(E.Value));
164   }
165 }
166
167 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
168                                                         ThunkOrdinal &Ord) {
169   auto ThunkNames = getThunkOrdinalNames();
170   for (const auto &E : ThunkNames) {
171     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
172   }
173 }
174
175 void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
176     IO &io, FrameCookieKind &FC) {
177   auto ThunkNames = getFrameCookieKindNames();
178   for (const auto &E : ThunkNames) {
179     io.enumCase(FC, E.Name.str().c_str(),
180                 static_cast<FrameCookieKind>(E.Value));
181   }
182 }
183
184 namespace llvm {
185 namespace yaml {
186 template <> struct MappingTraits<LocalVariableAddrRange> {
187   static void mapping(IO &io, LocalVariableAddrRange &Range) {
188     io.mapRequired("OffsetStart", Range.OffsetStart);
189     io.mapRequired("ISectStart", Range.ISectStart);
190     io.mapRequired("Range", Range.Range);
191   }
192 };
193 template <> struct MappingTraits<LocalVariableAddrGap> {
194   static void mapping(IO &io, LocalVariableAddrGap &Gap) {
195     io.mapRequired("GapStartOffset", Gap.GapStartOffset);
196     io.mapRequired("Range", Gap.Range);
197   }
198 };
199 } // namespace yaml
200 } // namespace llvm
201
202 namespace llvm {
203 namespace CodeViewYAML {
204 namespace detail {
205
206 struct SymbolRecordBase {
207   codeview::SymbolKind Kind;
208
209   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
210   virtual ~SymbolRecordBase() = default;
211
212   virtual void map(yaml::IO &io) = 0;
213   virtual codeview::CVSymbol
214   toCodeViewSymbol(BumpPtrAllocator &Allocator,
215                    CodeViewContainer Container) const = 0;
216   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
217 };
218
219 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
220   explicit SymbolRecordImpl(codeview::SymbolKind K)
221       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
222
223   void map(yaml::IO &io) override;
224
225   codeview::CVSymbol
226   toCodeViewSymbol(BumpPtrAllocator &Allocator,
227                    CodeViewContainer Container) const override {
228     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
229   }
230
231   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
232     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
233   }
234
235   mutable T Symbol;
236 };
237
238 struct UnknownSymbolRecord : public SymbolRecordBase {
239   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
240
241   void map(yaml::IO &io) override;
242
243   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
244                             CodeViewContainer Container) const override {
245     RecordPrefix Prefix;
246     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
247     Prefix.RecordKind = Kind;
248     Prefix.RecordLen = TotalLen - 2;
249     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
250     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
251     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
252     return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
253   }
254
255   Error fromCodeViewSymbol(CVSymbol CVS) override {
256     this->Kind = CVS.kind();
257     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
258     return Error::success();
259   }
260
261   std::vector<uint8_t> Data;
262 };
263
264 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
265
266 void UnknownSymbolRecord::map(yaml::IO &io) {
267   yaml::BinaryRef Binary;
268   if (io.outputting())
269     Binary = yaml::BinaryRef(Data);
270   io.mapRequired("Data", Binary);
271   if (!io.outputting()) {
272     std::string Str;
273     raw_string_ostream OS(Str);
274     Binary.writeAsBinary(OS);
275     OS.flush();
276     Data.assign(Str.begin(), Str.end());
277   }
278 }
279
280 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
281   IO.mapRequired("Parent", Symbol.Parent);
282   IO.mapRequired("End", Symbol.End);
283   IO.mapRequired("Next", Symbol.Next);
284   IO.mapRequired("Off", Symbol.Offset);
285   IO.mapRequired("Seg", Symbol.Segment);
286   IO.mapRequired("Len", Symbol.Length);
287   IO.mapRequired("Ordinal", Symbol.Thunk);
288 }
289
290 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
291   IO.mapRequired("Type", Symbol.Type);
292   IO.mapRequired("Size", Symbol.Size);
293   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
294   IO.mapRequired("TargetOff", Symbol.TargetOffset);
295   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
296   IO.mapRequired("TargetSection", Symbol.TargetSection);
297 }
298
299 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
300   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
301   IO.mapRequired("Alignment", Symbol.Alignment);
302   IO.mapRequired("Rva", Symbol.Rva);
303   IO.mapRequired("Length", Symbol.Length);
304   IO.mapRequired("Characteristics", Symbol.Characteristics);
305   IO.mapRequired("Name", Symbol.Name);
306 }
307
308 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
309   IO.mapRequired("Size", Symbol.Size);
310   IO.mapRequired("Characteristics", Symbol.Characteristics);
311   IO.mapRequired("Offset", Symbol.Offset);
312   IO.mapRequired("Segment", Symbol.Segment);
313   IO.mapRequired("Name", Symbol.Name);
314 }
315
316 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
317   IO.mapRequired("Ordinal", Symbol.Ordinal);
318   IO.mapRequired("Flags", Symbol.Flags);
319   IO.mapRequired("Name", Symbol.Name);
320 }
321
322 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
323   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
324   IO.mapOptional("PtrEnd", Symbol.End, 0U);
325   IO.mapOptional("PtrNext", Symbol.Next, 0U);
326   IO.mapRequired("CodeSize", Symbol.CodeSize);
327   IO.mapRequired("DbgStart", Symbol.DbgStart);
328   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
329   IO.mapRequired("FunctionType", Symbol.FunctionType);
330   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
331   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
332   IO.mapRequired("Flags", Symbol.Flags);
333   IO.mapRequired("DisplayName", Symbol.Name);
334 }
335
336 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
337   IO.mapRequired("Type", Symbol.Index);
338   IO.mapRequired("Seg", Symbol.Register);
339   IO.mapRequired("Name", Symbol.Name);
340 }
341
342 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
343   IO.mapRequired("Flags", Symbol.Flags);
344   IO.mapOptional("Offset", Symbol.Offset, 0U);
345   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
346   IO.mapRequired("Name", Symbol.Name);
347 }
348
349 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
350   IO.mapRequired("SumName", Symbol.SumName);
351   IO.mapRequired("SymOffset", Symbol.SymOffset);
352   IO.mapRequired("Mod", Symbol.Module);
353   IO.mapRequired("Name", Symbol.Name);
354 }
355
356 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
357   IO.mapRequired("Entries", Symbol.Fields);
358 }
359
360 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
361   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
362   IO.mapOptional("PtrEnd", Symbol.End, 0U);
363   IO.mapRequired("Inlinee", Symbol.Inlinee);
364   // TODO: The binary annotations
365 }
366
367 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
368   IO.mapRequired("Type", Symbol.Type);
369   IO.mapRequired("Flags", Symbol.Flags);
370
371   IO.mapRequired("VarName", Symbol.Name);
372 }
373
374 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
375   IO.mapRequired("Program", Symbol.Program);
376   IO.mapRequired("Range", Symbol.Range);
377   IO.mapRequired("Gaps", Symbol.Gaps);
378 }
379
380 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
381   IO.mapRequired("Program", Symbol.Program);
382   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
383   IO.mapRequired("Range", Symbol.Range);
384   IO.mapRequired("Gaps", Symbol.Gaps);
385 }
386
387 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
388   IO.mapRequired("Register", Symbol.Hdr.Register);
389   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
390   IO.mapRequired("Range", Symbol.Range);
391   IO.mapRequired("Gaps", Symbol.Gaps);
392 }
393
394 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
395   IO.mapRequired("Offset", Symbol.Offset);
396   IO.mapRequired("Range", Symbol.Range);
397   IO.mapRequired("Gaps", Symbol.Gaps);
398 }
399
400 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
401   IO.mapRequired("Register", Symbol.Hdr.Register);
402   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
403   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
404   IO.mapRequired("Range", Symbol.Range);
405   IO.mapRequired("Gaps", Symbol.Gaps);
406 }
407
408 template <>
409 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
410   IO.mapRequired("Register", Symbol.Offset);
411 }
412
413 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
414   IO.mapRequired("Register", Symbol.Hdr.Register);
415   IO.mapRequired("Flags", Symbol.Hdr.Flags);
416   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
417   IO.mapRequired("Range", Symbol.Range);
418   IO.mapRequired("Gaps", Symbol.Gaps);
419 }
420
421 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
422   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
423   IO.mapOptional("PtrEnd", Symbol.End, 0U);
424   IO.mapRequired("CodeSize", Symbol.CodeSize);
425   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
426   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
427   IO.mapRequired("BlockName", Symbol.Name);
428 }
429
430 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
431   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
432   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
433   IO.mapRequired("Flags", Symbol.Flags);
434   IO.mapRequired("Flags", Symbol.Flags);
435   IO.mapRequired("DisplayName", Symbol.Name);
436 }
437
438 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
439   IO.mapRequired("Signature", Symbol.Signature);
440   IO.mapRequired("ObjectName", Symbol.Name);
441 }
442
443 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
444   IO.mapRequired("Flags", Symbol.Flags);
445   IO.mapRequired("Machine", Symbol.Machine);
446   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
447   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
448   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
449   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
450   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
451   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
452   IO.mapRequired("Version", Symbol.Version);
453 }
454
455 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
456   IO.mapRequired("Flags", Symbol.Flags);
457   IO.mapRequired("Machine", Symbol.Machine);
458   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
459   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
460   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
461   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
462   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
463   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
464   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
465   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
466   IO.mapRequired("Version", Symbol.Version);
467 }
468
469 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
470   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
471   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
472   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
473   IO.mapRequired("BytesOfCalleeSavedRegisters",
474                  Symbol.BytesOfCalleeSavedRegisters);
475   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
476   IO.mapRequired("SectionIdOfExceptionHandler",
477                  Symbol.SectionIdOfExceptionHandler);
478   IO.mapRequired("Flags", Symbol.Flags);
479 }
480
481 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
482   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
483   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
484   IO.mapRequired("Type", Symbol.Type);
485 }
486
487 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
488   IO.mapRequired("Index", Symbol.Index);
489   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
490   IO.mapRequired("Flags", Symbol.Flags);
491   IO.mapRequired("Name", Symbol.Name);
492 }
493
494 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
495   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
496   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
497   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
498   IO.mapRequired("Type", Symbol.Type);
499 }
500
501 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
502   IO.mapRequired("Register", Symbol.Register);
503   IO.mapRequired("CookieKind", Symbol.CookieKind);
504   IO.mapRequired("Flags", Symbol.Flags);
505 }
506
507 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
508   IO.mapRequired("FuncID", Symbol.Indices);
509 }
510
511 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
512   IO.mapRequired("Type", Symbol.Type);
513   IO.mapRequired("UDTName", Symbol.Name);
514 }
515
516 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
517   IO.mapRequired("BuildId", Symbol.BuildId);
518 }
519
520 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
521   IO.mapRequired("Offset", Symbol.Offset);
522   IO.mapRequired("Type", Symbol.Type);
523   IO.mapRequired("VarName", Symbol.Name);
524 }
525
526 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
527   IO.mapRequired("Offset", Symbol.Offset);
528   IO.mapRequired("Type", Symbol.Type);
529   IO.mapRequired("Register", Symbol.Register);
530   IO.mapRequired("VarName", Symbol.Name);
531 }
532
533 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
534   IO.mapRequired("Type", Symbol.Type);
535   IO.mapRequired("Value", Symbol.Value);
536   IO.mapRequired("Name", Symbol.Name);
537 }
538
539 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
540   IO.mapRequired("Type", Symbol.Type);
541   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
542   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
543   IO.mapRequired("DisplayName", Symbol.Name);
544 }
545
546 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
547   IO.mapRequired("Type", Symbol.Type);
548   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
549   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
550   IO.mapRequired("DisplayName", Symbol.Name);
551 }
552
553 template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
554   IO.mapRequired("Namespace", Symbol.Name);
555 }
556
557 } // end namespace detail
558 } // end namespace CodeViewYAML
559 } // end namespace llvm
560
561 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
562     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
563   return Symbol->toCodeViewSymbol(Allocator, Container);
564 }
565
566 namespace llvm {
567 namespace yaml {
568
569 template <> struct MappingTraits<SymbolRecordBase> {
570   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
571 };
572
573 } // end namespace yaml
574 } // end namespace llvm
575
576 template <typename SymbolType>
577 static inline Expected<CodeViewYAML::SymbolRecord>
578 fromCodeViewSymbolImpl(CVSymbol Symbol) {
579   CodeViewYAML::SymbolRecord Result;
580
581   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
582   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
583     return std::move(EC);
584   Result.Symbol = Impl;
585   return Result;
586 }
587
588 Expected<CodeViewYAML::SymbolRecord>
589 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
590 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
591   case EnumName:                                                               \
592     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
593 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
594   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
595   switch (Symbol.kind()) {
596 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
597   default:
598     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
599   }
600   return make_error<CodeViewError>(cv_error_code::corrupt_record);
601 }
602
603 template <typename ConcreteType>
604 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
605                                 CodeViewYAML::SymbolRecord &Obj) {
606   if (!IO.outputting())
607     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
608
609   IO.mapRequired(Class, *Obj.Symbol);
610 }
611
612 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
613     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
614   SymbolKind Kind;
615   if (IO.outputting())
616     Kind = Obj.Symbol->Kind;
617   IO.mapRequired("Kind", Kind);
618
619 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
620   case EnumName:                                                               \
621     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
622                                                      Obj);                     \
623     break;
624 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
625   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
626   switch (Kind) {
627 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
628   default:
629     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
630   }
631 }