[AMDGPU][AsmParser][NFC] Translate parsed MIMG instructions to MCInsts automatically.
[llvm-project.git] / llvm / lib / ObjectYAML / CodeViewYAMLSymbols.cpp
blob8d2028abfe9b41bb81a0d1f6c5f780075d2aefc3
1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines classes for handling the YAML representation of CodeView
10 // Debug Info.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/DebugInfo/CodeView/CodeView.h"
18 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
19 #include "llvm/DebugInfo/CodeView/EnumTables.h"
20 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
21 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
22 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
23 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
24 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
25 #include "llvm/ObjectYAML/YAML.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/Support/ScopedPrinter.h"
29 #include "llvm/Support/YAMLTraits.h"
30 #include <algorithm>
31 #include <cstdint>
32 #include <cstring>
33 #include <optional>
34 #include <string>
35 #include <vector>
37 using namespace llvm;
38 using namespace llvm::codeview;
39 using namespace llvm::CodeViewYAML;
40 using namespace llvm::CodeViewYAML::detail;
41 using namespace llvm::yaml;
43 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
44 LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
46 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
47 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
48 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
50 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
51 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
53 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
54 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
55 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
56 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
57 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
58 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
59 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
61 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
62 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
63 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
65 LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
67 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
69 StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
70 return ScalarTraits<StringRef>::input(S, V, T.value);
73 void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
74 raw_ostream &R) {
75 ScalarTraits<StringRef>::output(T.value, V, R);
78 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
79 SymbolKind &Value) {
80 auto SymbolNames = getSymbolTypeNames();
81 for (const auto &E : SymbolNames)
82 io.enumCase(Value, E.Name.str().c_str(), E.Value);
85 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
86 CompileSym2Flags &Flags) {
87 auto FlagNames = getCompileSym2FlagNames();
88 for (const auto &E : FlagNames) {
89 io.bitSetCase(Flags, E.Name.str().c_str(),
90 static_cast<CompileSym2Flags>(E.Value));
94 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
95 CompileSym3Flags &Flags) {
96 auto FlagNames = getCompileSym3FlagNames();
97 for (const auto &E : FlagNames) {
98 io.bitSetCase(Flags, E.Name.str().c_str(),
99 static_cast<CompileSym3Flags>(E.Value));
103 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
104 auto FlagNames = getExportSymFlagNames();
105 for (const auto &E : FlagNames) {
106 io.bitSetCase(Flags, E.Name.str().c_str(),
107 static_cast<ExportFlags>(E.Value));
111 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
112 auto FlagNames = getPublicSymFlagNames();
113 for (const auto &E : FlagNames) {
114 io.bitSetCase(Flags, E.Name.str().c_str(),
115 static_cast<PublicSymFlags>(E.Value));
119 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
120 auto FlagNames = getLocalFlagNames();
121 for (const auto &E : FlagNames) {
122 io.bitSetCase(Flags, E.Name.str().c_str(),
123 static_cast<LocalSymFlags>(E.Value));
127 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
128 auto FlagNames = getProcSymFlagNames();
129 for (const auto &E : FlagNames) {
130 io.bitSetCase(Flags, E.Name.str().c_str(),
131 static_cast<ProcSymFlags>(E.Value));
135 void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
136 IO &io, FrameProcedureOptions &Flags) {
137 auto FlagNames = getFrameProcSymFlagNames();
138 for (const auto &E : FlagNames) {
139 io.bitSetCase(Flags, E.Name.str().c_str(),
140 static_cast<FrameProcedureOptions>(E.Value));
144 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
145 auto CpuNames = getCPUTypeNames();
146 for (const auto &E : CpuNames) {
147 io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
151 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
152 const auto *Header = static_cast<COFF::header *>(io.getContext());
153 assert(Header && "The IO context is not initialized");
155 std::optional<CPUType> CpuType;
156 ArrayRef<EnumEntry<uint16_t>> RegNames;
158 switch (Header->Machine) {
159 case COFF::IMAGE_FILE_MACHINE_I386:
160 CpuType = CPUType::Pentium3;
161 break;
162 case COFF::IMAGE_FILE_MACHINE_AMD64:
163 CpuType = CPUType::X64;
164 break;
165 case COFF::IMAGE_FILE_MACHINE_ARMNT:
166 CpuType = CPUType::ARMNT;
167 break;
168 case COFF::IMAGE_FILE_MACHINE_ARM64:
169 case COFF::IMAGE_FILE_MACHINE_ARM64EC:
170 case COFF::IMAGE_FILE_MACHINE_ARM64X:
171 CpuType = CPUType::ARM64;
172 break;
175 if (CpuType)
176 RegNames = getRegisterNames(*CpuType);
178 for (const auto &E : RegNames) {
179 io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
181 io.enumFallback<Hex16>(Reg);
184 void ScalarEnumerationTraits<TrampolineType>::enumeration(
185 IO &io, TrampolineType &Tramp) {
186 auto TrampNames = getTrampolineNames();
187 for (const auto &E : TrampNames) {
188 io.enumCase(Tramp, E.Name.str().c_str(),
189 static_cast<TrampolineType>(E.Value));
193 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
194 ThunkOrdinal &Ord) {
195 auto ThunkNames = getThunkOrdinalNames();
196 for (const auto &E : ThunkNames) {
197 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
201 void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
202 IO &io, FrameCookieKind &FC) {
203 auto ThunkNames = getFrameCookieKindNames();
204 for (const auto &E : ThunkNames) {
205 io.enumCase(FC, E.Name.str().c_str(),
206 static_cast<FrameCookieKind>(E.Value));
210 namespace llvm {
211 namespace yaml {
212 template <> struct MappingTraits<LocalVariableAddrRange> {
213 static void mapping(IO &io, LocalVariableAddrRange &Range) {
214 io.mapRequired("OffsetStart", Range.OffsetStart);
215 io.mapRequired("ISectStart", Range.ISectStart);
216 io.mapRequired("Range", Range.Range);
219 template <> struct MappingTraits<LocalVariableAddrGap> {
220 static void mapping(IO &io, LocalVariableAddrGap &Gap) {
221 io.mapRequired("GapStartOffset", Gap.GapStartOffset);
222 io.mapRequired("Range", Gap.Range);
225 } // namespace yaml
226 } // namespace llvm
228 namespace llvm {
229 namespace CodeViewYAML {
230 namespace detail {
232 struct SymbolRecordBase {
233 codeview::SymbolKind Kind;
235 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
236 virtual ~SymbolRecordBase() = default;
238 virtual void map(yaml::IO &io) = 0;
239 virtual codeview::CVSymbol
240 toCodeViewSymbol(BumpPtrAllocator &Allocator,
241 CodeViewContainer Container) const = 0;
242 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
245 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
246 explicit SymbolRecordImpl(codeview::SymbolKind K)
247 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
249 void map(yaml::IO &io) override;
251 codeview::CVSymbol
252 toCodeViewSymbol(BumpPtrAllocator &Allocator,
253 CodeViewContainer Container) const override {
254 return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
257 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
258 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
261 mutable T Symbol;
264 struct UnknownSymbolRecord : public SymbolRecordBase {
265 explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
267 void map(yaml::IO &io) override;
269 CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
270 CodeViewContainer Container) const override {
271 RecordPrefix Prefix;
272 uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
273 Prefix.RecordKind = Kind;
274 Prefix.RecordLen = TotalLen - 2;
275 uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
276 ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
277 ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
278 return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
281 Error fromCodeViewSymbol(CVSymbol CVS) override {
282 this->Kind = CVS.kind();
283 Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
284 return Error::success();
287 std::vector<uint8_t> Data;
290 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
292 void UnknownSymbolRecord::map(yaml::IO &io) {
293 yaml::BinaryRef Binary;
294 if (io.outputting())
295 Binary = yaml::BinaryRef(Data);
296 io.mapRequired("Data", Binary);
297 if (!io.outputting()) {
298 std::string Str;
299 raw_string_ostream OS(Str);
300 Binary.writeAsBinary(OS);
301 OS.flush();
302 Data.assign(Str.begin(), Str.end());
306 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
307 IO.mapRequired("Parent", Symbol.Parent);
308 IO.mapRequired("End", Symbol.End);
309 IO.mapRequired("Next", Symbol.Next);
310 IO.mapRequired("Off", Symbol.Offset);
311 IO.mapRequired("Seg", Symbol.Segment);
312 IO.mapRequired("Len", Symbol.Length);
313 IO.mapRequired("Ordinal", Symbol.Thunk);
316 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
317 IO.mapRequired("Type", Symbol.Type);
318 IO.mapRequired("Size", Symbol.Size);
319 IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
320 IO.mapRequired("TargetOff", Symbol.TargetOffset);
321 IO.mapRequired("ThunkSection", Symbol.ThunkSection);
322 IO.mapRequired("TargetSection", Symbol.TargetSection);
325 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
326 IO.mapRequired("SectionNumber", Symbol.SectionNumber);
327 IO.mapRequired("Alignment", Symbol.Alignment);
328 IO.mapRequired("Rva", Symbol.Rva);
329 IO.mapRequired("Length", Symbol.Length);
330 IO.mapRequired("Characteristics", Symbol.Characteristics);
331 IO.mapRequired("Name", Symbol.Name);
334 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
335 IO.mapRequired("Size", Symbol.Size);
336 IO.mapRequired("Characteristics", Symbol.Characteristics);
337 IO.mapRequired("Offset", Symbol.Offset);
338 IO.mapRequired("Segment", Symbol.Segment);
339 IO.mapRequired("Name", Symbol.Name);
342 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
343 IO.mapRequired("Ordinal", Symbol.Ordinal);
344 IO.mapRequired("Flags", Symbol.Flags);
345 IO.mapRequired("Name", Symbol.Name);
348 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
349 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
350 IO.mapOptional("PtrEnd", Symbol.End, 0U);
351 IO.mapOptional("PtrNext", Symbol.Next, 0U);
352 IO.mapRequired("CodeSize", Symbol.CodeSize);
353 IO.mapRequired("DbgStart", Symbol.DbgStart);
354 IO.mapRequired("DbgEnd", Symbol.DbgEnd);
355 IO.mapRequired("FunctionType", Symbol.FunctionType);
356 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
357 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
358 IO.mapRequired("Flags", Symbol.Flags);
359 IO.mapRequired("DisplayName", Symbol.Name);
362 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
363 IO.mapRequired("Type", Symbol.Index);
364 IO.mapRequired("Seg", Symbol.Register);
365 IO.mapRequired("Name", Symbol.Name);
368 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
369 IO.mapRequired("Flags", Symbol.Flags);
370 IO.mapOptional("Offset", Symbol.Offset, 0U);
371 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
372 IO.mapRequired("Name", Symbol.Name);
375 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
376 IO.mapRequired("SumName", Symbol.SumName);
377 IO.mapRequired("SymOffset", Symbol.SymOffset);
378 IO.mapRequired("Mod", Symbol.Module);
379 IO.mapRequired("Name", Symbol.Name);
382 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
383 IO.mapRequired("Entries", Symbol.Fields);
386 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
387 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
388 IO.mapOptional("PtrEnd", Symbol.End, 0U);
389 IO.mapRequired("Inlinee", Symbol.Inlinee);
390 // TODO: The binary annotations
393 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
394 IO.mapRequired("Type", Symbol.Type);
395 IO.mapRequired("Flags", Symbol.Flags);
397 IO.mapRequired("VarName", Symbol.Name);
400 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
401 IO.mapRequired("Program", Symbol.Program);
402 IO.mapRequired("Range", Symbol.Range);
403 IO.mapRequired("Gaps", Symbol.Gaps);
406 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
407 IO.mapRequired("Program", Symbol.Program);
408 IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
409 IO.mapRequired("Range", Symbol.Range);
410 IO.mapRequired("Gaps", Symbol.Gaps);
413 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
414 IO.mapRequired("Register", Symbol.Hdr.Register);
415 IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
416 IO.mapRequired("Range", Symbol.Range);
417 IO.mapRequired("Gaps", Symbol.Gaps);
420 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
421 IO.mapRequired("Offset", Symbol.Hdr.Offset);
422 IO.mapRequired("Range", Symbol.Range);
423 IO.mapRequired("Gaps", Symbol.Gaps);
426 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
427 IO.mapRequired("Register", Symbol.Hdr.Register);
428 IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
429 IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
430 IO.mapRequired("Range", Symbol.Range);
431 IO.mapRequired("Gaps", Symbol.Gaps);
434 template <>
435 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
436 IO.mapRequired("Register", Symbol.Offset);
439 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
440 IO.mapRequired("Register", Symbol.Hdr.Register);
441 IO.mapRequired("Flags", Symbol.Hdr.Flags);
442 IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
443 IO.mapRequired("Range", Symbol.Range);
444 IO.mapRequired("Gaps", Symbol.Gaps);
447 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
448 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
449 IO.mapOptional("PtrEnd", Symbol.End, 0U);
450 IO.mapRequired("CodeSize", Symbol.CodeSize);
451 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
452 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
453 IO.mapRequired("BlockName", Symbol.Name);
456 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
457 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
458 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
459 IO.mapRequired("Flags", Symbol.Flags);
460 IO.mapRequired("Flags", Symbol.Flags);
461 IO.mapRequired("DisplayName", Symbol.Name);
464 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
465 IO.mapRequired("Signature", Symbol.Signature);
466 IO.mapRequired("ObjectName", Symbol.Name);
469 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
470 IO.mapRequired("Flags", Symbol.Flags);
471 IO.mapRequired("Machine", Symbol.Machine);
472 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
473 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
474 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
475 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
476 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
477 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
478 IO.mapRequired("Version", Symbol.Version);
481 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
482 IO.mapRequired("Flags", Symbol.Flags);
483 IO.mapRequired("Machine", Symbol.Machine);
484 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
485 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
486 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
487 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
488 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
489 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
490 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
491 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
492 IO.mapRequired("Version", Symbol.Version);
495 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
496 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
497 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
498 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
499 IO.mapRequired("BytesOfCalleeSavedRegisters",
500 Symbol.BytesOfCalleeSavedRegisters);
501 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
502 IO.mapRequired("SectionIdOfExceptionHandler",
503 Symbol.SectionIdOfExceptionHandler);
504 IO.mapRequired("Flags", Symbol.Flags);
507 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
508 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
509 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
510 IO.mapRequired("Type", Symbol.Type);
513 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
514 IO.mapRequired("Index", Symbol.Index);
515 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
516 IO.mapRequired("Flags", Symbol.Flags);
517 IO.mapRequired("Name", Symbol.Name);
520 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
521 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
522 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
523 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
524 IO.mapRequired("Type", Symbol.Type);
527 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
528 IO.mapRequired("Register", Symbol.Register);
529 IO.mapRequired("CookieKind", Symbol.CookieKind);
530 IO.mapRequired("Flags", Symbol.Flags);
533 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
534 IO.mapRequired("FuncID", Symbol.Indices);
537 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
538 IO.mapRequired("Type", Symbol.Type);
539 IO.mapRequired("UDTName", Symbol.Name);
542 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
543 IO.mapRequired("BuildId", Symbol.BuildId);
546 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
547 IO.mapRequired("Offset", Symbol.Offset);
548 IO.mapRequired("Type", Symbol.Type);
549 IO.mapRequired("VarName", Symbol.Name);
552 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
553 IO.mapRequired("Offset", Symbol.Offset);
554 IO.mapRequired("Type", Symbol.Type);
555 IO.mapRequired("Register", Symbol.Register);
556 IO.mapRequired("VarName", Symbol.Name);
559 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
560 IO.mapRequired("Type", Symbol.Type);
561 IO.mapRequired("Value", Symbol.Value);
562 IO.mapRequired("Name", Symbol.Name);
565 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
566 IO.mapRequired("Type", Symbol.Type);
567 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
568 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
569 IO.mapRequired("DisplayName", Symbol.Name);
572 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
573 IO.mapRequired("Type", Symbol.Type);
574 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
575 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
576 IO.mapRequired("DisplayName", Symbol.Name);
579 template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
580 IO.mapRequired("Namespace", Symbol.Name);
583 template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
584 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
585 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
586 IO.mapRequired("Strings", Symbol.Strings);
589 } // end namespace detail
590 } // end namespace CodeViewYAML
591 } // end namespace llvm
593 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
594 BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
595 return Symbol->toCodeViewSymbol(Allocator, Container);
598 namespace llvm {
599 namespace yaml {
601 template <> struct MappingTraits<SymbolRecordBase> {
602 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
605 } // end namespace yaml
606 } // end namespace llvm
608 template <typename SymbolType>
609 static inline Expected<CodeViewYAML::SymbolRecord>
610 fromCodeViewSymbolImpl(CVSymbol Symbol) {
611 CodeViewYAML::SymbolRecord Result;
613 auto Impl = std::make_shared<SymbolType>(Symbol.kind());
614 if (auto EC = Impl->fromCodeViewSymbol(Symbol))
615 return std::move(EC);
616 Result.Symbol = Impl;
617 return Result;
620 Expected<CodeViewYAML::SymbolRecord>
621 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
622 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
623 case EnumName: \
624 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
625 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
626 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
627 switch (Symbol.kind()) {
628 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
629 default:
630 return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
632 return make_error<CodeViewError>(cv_error_code::corrupt_record);
635 template <typename ConcreteType>
636 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
637 CodeViewYAML::SymbolRecord &Obj) {
638 if (!IO.outputting())
639 Obj.Symbol = std::make_shared<ConcreteType>(Kind);
641 IO.mapRequired(Class, *Obj.Symbol);
644 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
645 IO &IO, CodeViewYAML::SymbolRecord &Obj) {
646 SymbolKind Kind;
647 if (IO.outputting())
648 Kind = Obj.Symbol->Kind;
649 IO.mapRequired("Kind", Kind);
651 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
652 case EnumName: \
653 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
654 Obj); \
655 break;
656 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
657 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
658 switch (Kind) {
659 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
660 default:
661 mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);