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