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