1aaad5744SZachary Turner //===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===//
2aaad5744SZachary Turner //
3aaad5744SZachary Turner //                     The LLVM Compiler Infrastructure
4aaad5744SZachary Turner //
5aaad5744SZachary Turner // This file is distributed under the University of Illinois Open Source
6aaad5744SZachary Turner // License. See LICENSE.TXT for details.
7aaad5744SZachary Turner //
8aaad5744SZachary Turner //===----------------------------------------------------------------------===//
9aaad5744SZachary Turner 
10aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
11aaad5744SZachary Turner #include "llvm/ADT/DenseMap.h"
12aaad5744SZachary Turner #include "llvm/ADT/SmallString.h"
13aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
14a9054dddSZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
1593839cb4SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h"
16*2d5c2cd3SZachary Turner #include "llvm/DebugInfo/CodeView/StringTable.h"
170d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
18aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
19aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
200d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
210d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
22aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/TypeIndex.h"
230d840744SZachary Turner #include "llvm/Support/Error.h"
24aaad5744SZachary Turner #include "llvm/Support/ScopedPrinter.h"
25aaad5744SZachary Turner 
26aaad5744SZachary Turner #include <system_error>
27aaad5744SZachary Turner 
28aaad5744SZachary Turner using namespace llvm;
29aaad5744SZachary Turner using namespace llvm::codeview;
30aaad5744SZachary Turner 
31aaad5744SZachary Turner namespace {
32aaad5744SZachary Turner /// Use this private dumper implementation to keep implementation details about
33aaad5744SZachary Turner /// the visitor out of SymbolDumper.h.
340d840744SZachary Turner class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
35aaad5744SZachary Turner public:
36629cb7d8SZachary Turner   CVSymbolDumperImpl(TypeDatabase &TypeDB, SymbolDumpDelegate *ObjDelegate,
373e78e2d4SZachary Turner                      ScopedPrinter &W, bool PrintRecordBytes)
38629cb7d8SZachary Turner       : TypeDB(TypeDB), ObjDelegate(ObjDelegate), W(W),
390d840744SZachary Turner         PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
40aaad5744SZachary Turner 
41aaad5744SZachary Turner /// CVSymbolVisitor overrides.
42aaad5744SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
430d840744SZachary Turner   Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
44aaad5744SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
45aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
46aaad5744SZachary Turner 
470d840744SZachary Turner   Error visitSymbolBegin(CVSymbol &Record) override;
480d840744SZachary Turner   Error visitSymbolEnd(CVSymbol &Record) override;
490d840744SZachary Turner   Error visitUnknownSymbol(CVSymbol &Record) override;
50aaad5744SZachary Turner 
51aaad5744SZachary Turner private:
52aaad5744SZachary Turner   void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
53aaad5744SZachary Turner                                    uint32_t RelocationOffset);
54aaad5744SZachary Turner   void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
55629cb7d8SZachary Turner   void printTypeIndex(StringRef FieldName, TypeIndex TI);
56aaad5744SZachary Turner 
57629cb7d8SZachary Turner   TypeDatabase &TypeDB;
58aaad5744SZachary Turner   SymbolDumpDelegate *ObjDelegate;
59aaad5744SZachary Turner   ScopedPrinter &W;
60aaad5744SZachary Turner 
61aaad5744SZachary Turner   bool PrintRecordBytes;
62aaad5744SZachary Turner   bool InFunctionScope;
63aaad5744SZachary Turner };
64aaad5744SZachary Turner }
65aaad5744SZachary Turner 
66aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrRange(
67aaad5744SZachary Turner     const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
68aaad5744SZachary Turner   DictScope S(W, "LocalVariableAddrRange");
69aaad5744SZachary Turner   if (ObjDelegate)
70aaad5744SZachary Turner     ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
71aaad5744SZachary Turner                                      Range.OffsetStart);
72aaad5744SZachary Turner   W.printHex("ISectStart", Range.ISectStart);
73aaad5744SZachary Turner   W.printHex("Range", Range.Range);
74aaad5744SZachary Turner }
75aaad5744SZachary Turner 
76aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrGap(
77aaad5744SZachary Turner     ArrayRef<LocalVariableAddrGap> Gaps) {
78aaad5744SZachary Turner   for (auto &Gap : Gaps) {
79aaad5744SZachary Turner     ListScope S(W, "LocalVariableAddrGap");
80aaad5744SZachary Turner     W.printHex("GapStartOffset", Gap.GapStartOffset);
81aaad5744SZachary Turner     W.printHex("Range", Gap.Range);
82aaad5744SZachary Turner   }
83aaad5744SZachary Turner }
84aaad5744SZachary Turner 
85629cb7d8SZachary Turner void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
86629cb7d8SZachary Turner   CVTypeDumper::printTypeIndex(W, FieldName, TI, TypeDB);
87629cb7d8SZachary Turner }
88629cb7d8SZachary Turner 
890d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
900d840744SZachary Turner   return Error::success();
91aaad5744SZachary Turner }
92aaad5744SZachary Turner 
930d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {
940d840744SZachary Turner   if (PrintRecordBytes && ObjDelegate)
950d840744SZachary Turner     ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());
960d840744SZachary Turner   return Error::success();
970d840744SZachary Turner }
980d840744SZachary Turner 
990d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
100aaad5744SZachary Turner   DictScope S(W, "BlockStart");
101aaad5744SZachary Turner 
102aaad5744SZachary Turner   StringRef LinkageName;
10346225b19SZachary Turner   W.printHex("PtrParent", Block.Parent);
10446225b19SZachary Turner   W.printHex("PtrEnd", Block.End);
10546225b19SZachary Turner   W.printHex("CodeSize", Block.CodeSize);
106aaad5744SZachary Turner   if (ObjDelegate) {
107aaad5744SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
10846225b19SZachary Turner                                      Block.CodeOffset, &LinkageName);
109aaad5744SZachary Turner   }
11046225b19SZachary Turner   W.printHex("Segment", Block.Segment);
111aaad5744SZachary Turner   W.printString("BlockName", Block.Name);
112aaad5744SZachary Turner   W.printString("LinkageName", LinkageName);
1130d840744SZachary Turner   return Error::success();
114aaad5744SZachary Turner }
115aaad5744SZachary Turner 
1160d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
1174caa1bf0SZachary Turner   DictScope S(W, "Thunk32");
11846225b19SZachary Turner   W.printNumber("Parent", Thunk.Parent);
11946225b19SZachary Turner   W.printNumber("End", Thunk.End);
12046225b19SZachary Turner   W.printNumber("Next", Thunk.Next);
12146225b19SZachary Turner   W.printNumber("Off", Thunk.Offset);
12246225b19SZachary Turner   W.printNumber("Seg", Thunk.Segment);
12346225b19SZachary Turner   W.printNumber("Len", Thunk.Length);
12446225b19SZachary Turner   W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());
1250d840744SZachary Turner   return Error::success();
1264caa1bf0SZachary Turner }
1274caa1bf0SZachary Turner 
1280d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
1294caa1bf0SZachary Turner                                            TrampolineSym &Tramp) {
1304caa1bf0SZachary Turner   DictScope S(W, "Trampoline");
13146225b19SZachary Turner   W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());
13246225b19SZachary Turner   W.printNumber("Size", Tramp.Size);
13346225b19SZachary Turner   W.printNumber("ThunkOff", Tramp.ThunkOffset);
13446225b19SZachary Turner   W.printNumber("TargetOff", Tramp.TargetOffset);
13546225b19SZachary Turner   W.printNumber("ThunkSection", Tramp.ThunkSection);
13646225b19SZachary Turner   W.printNumber("TargetSection", Tramp.TargetSection);
1370d840744SZachary Turner   return Error::success();
1384caa1bf0SZachary Turner }
1394caa1bf0SZachary Turner 
1400d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {
1414caa1bf0SZachary Turner   DictScope S(W, "Section");
14246225b19SZachary Turner   W.printNumber("SectionNumber", Section.SectionNumber);
14346225b19SZachary Turner   W.printNumber("Alignment", Section.Alignment);
14446225b19SZachary Turner   W.printNumber("Rva", Section.Rva);
14546225b19SZachary Turner   W.printNumber("Length", Section.Length);
14646225b19SZachary Turner   W.printFlags("Characteristics", Section.Characteristics,
14793839cb4SZachary Turner                getImageSectionCharacteristicNames(),
14893839cb4SZachary Turner                COFF::SectionCharacteristics(0x00F00000));
14993839cb4SZachary Turner 
1504caa1bf0SZachary Turner   W.printString("Name", Section.Name);
1510d840744SZachary Turner   return Error::success();
1524caa1bf0SZachary Turner }
1534caa1bf0SZachary Turner 
1540d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
1554caa1bf0SZachary Turner                                            CoffGroupSym &CoffGroup) {
1564caa1bf0SZachary Turner   DictScope S(W, "COFF Group");
15746225b19SZachary Turner   W.printNumber("Size", CoffGroup.Size);
15846225b19SZachary Turner   W.printFlags("Characteristics", CoffGroup.Characteristics,
15993839cb4SZachary Turner                getImageSectionCharacteristicNames(),
16093839cb4SZachary Turner                COFF::SectionCharacteristics(0x00F00000));
16146225b19SZachary Turner   W.printNumber("Offset", CoffGroup.Offset);
16246225b19SZachary Turner   W.printNumber("Segment", CoffGroup.Segment);
1634caa1bf0SZachary Turner   W.printString("Name", CoffGroup.Name);
1640d840744SZachary Turner   return Error::success();
1654caa1bf0SZachary Turner }
1664caa1bf0SZachary Turner 
1670d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
168aaad5744SZachary Turner                                            BPRelativeSym &BPRel) {
169aaad5744SZachary Turner   DictScope S(W, "BPRelativeSym");
170aaad5744SZachary Turner 
17146225b19SZachary Turner   W.printNumber("Offset", BPRel.Offset);
172629cb7d8SZachary Turner   printTypeIndex("Type", BPRel.Type);
173aaad5744SZachary Turner   W.printString("VarName", BPRel.Name);
1740d840744SZachary Turner   return Error::success();
175aaad5744SZachary Turner }
176aaad5744SZachary Turner 
1770d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
178aaad5744SZachary Turner                                            BuildInfoSym &BuildInfo) {
179aaad5744SZachary Turner   DictScope S(W, "BuildInfo");
180aaad5744SZachary Turner 
18146225b19SZachary Turner   W.printNumber("BuildId", BuildInfo.BuildId);
1820d840744SZachary Turner   return Error::success();
183aaad5744SZachary Turner }
184aaad5744SZachary Turner 
1850d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
186aaad5744SZachary Turner                                            CallSiteInfoSym &CallSiteInfo) {
187aaad5744SZachary Turner   DictScope S(W, "CallSiteInfo");
188aaad5744SZachary Turner 
189aaad5744SZachary Turner   StringRef LinkageName;
190aaad5744SZachary Turner   if (ObjDelegate) {
19146225b19SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset",
19246225b19SZachary Turner                                      CallSiteInfo.getRelocationOffset(),
19346225b19SZachary Turner                                      CallSiteInfo.CodeOffset, &LinkageName);
194aaad5744SZachary Turner   }
19546225b19SZachary Turner   W.printHex("Segment", CallSiteInfo.Segment);
196629cb7d8SZachary Turner   printTypeIndex("Type", CallSiteInfo.Type);
197aaad5744SZachary Turner   if (!LinkageName.empty())
198aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
1990d840744SZachary Turner   return Error::success();
200aaad5744SZachary Turner }
201aaad5744SZachary Turner 
2020d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
2034caa1bf0SZachary Turner                                            EnvBlockSym &EnvBlock) {
2044caa1bf0SZachary Turner   DictScope S(W, "EnvBlock");
2054caa1bf0SZachary Turner 
2064caa1bf0SZachary Turner   ListScope L(W, "Entries");
2074caa1bf0SZachary Turner   for (auto Entry : EnvBlock.Fields) {
2084caa1bf0SZachary Turner     W.printString(Entry);
2094caa1bf0SZachary Turner   }
2100d840744SZachary Turner   return Error::success();
2114caa1bf0SZachary Turner }
2124caa1bf0SZachary Turner 
2130d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
2144caa1bf0SZachary Turner                                            FileStaticSym &FileStatic) {
2154caa1bf0SZachary Turner   DictScope S(W, "FileStatic");
21646225b19SZachary Turner   W.printNumber("Index", FileStatic.Index);
21746225b19SZachary Turner   W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
21846225b19SZachary Turner   W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
2194caa1bf0SZachary Turner   W.printString("Name", FileStatic.Name);
2200d840744SZachary Turner   return Error::success();
2214caa1bf0SZachary Turner }
2224caa1bf0SZachary Turner 
2230d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
2249f054d42SZachary Turner   DictScope S(W, "Export");
22546225b19SZachary Turner   W.printNumber("Ordinal", Export.Ordinal);
22646225b19SZachary Turner   W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());
2279f054d42SZachary Turner   W.printString("Name", Export.Name);
2280d840744SZachary Turner   return Error::success();
2299f054d42SZachary Turner }
2309f054d42SZachary Turner 
2310d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
2324caa1bf0SZachary Turner                                            Compile2Sym &Compile2) {
2334caa1bf0SZachary Turner   DictScope S(W, "CompilerFlags2");
2344caa1bf0SZachary Turner 
23546225b19SZachary Turner   W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());
23646225b19SZachary Turner   W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());
23746225b19SZachary Turner   W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
2384caa1bf0SZachary Turner   std::string FrontendVersion;
2394caa1bf0SZachary Turner   {
2404caa1bf0SZachary Turner     raw_string_ostream Out(FrontendVersion);
24146225b19SZachary Turner     Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor
24246225b19SZachary Turner         << '.' << Compile2.VersionFrontendBuild;
2434caa1bf0SZachary Turner   }
2444caa1bf0SZachary Turner   std::string BackendVersion;
2454caa1bf0SZachary Turner   {
2464caa1bf0SZachary Turner     raw_string_ostream Out(BackendVersion);
24746225b19SZachary Turner     Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor
24846225b19SZachary Turner         << '.' << Compile2.VersionBackendBuild;
2494caa1bf0SZachary Turner   }
2504caa1bf0SZachary Turner   W.printString("FrontendVersion", FrontendVersion);
2514caa1bf0SZachary Turner   W.printString("BackendVersion", BackendVersion);
2524caa1bf0SZachary Turner   W.printString("VersionName", Compile2.Version);
2530d840744SZachary Turner   return Error::success();
2544caa1bf0SZachary Turner }
2554caa1bf0SZachary Turner 
2560d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
257aaad5744SZachary Turner                                            Compile3Sym &Compile3) {
2584caa1bf0SZachary Turner   DictScope S(W, "CompilerFlags3");
259aaad5744SZachary Turner 
26046225b19SZachary Turner   W.printEnum("Language", Compile3.getLanguage(), getSourceLanguageNames());
26146225b19SZachary Turner   W.printFlags("Flags", Compile3.getFlags(), getCompileSym3FlagNames());
26246225b19SZachary Turner   W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
263aaad5744SZachary Turner   std::string FrontendVersion;
264aaad5744SZachary Turner   {
265aaad5744SZachary Turner     raw_string_ostream Out(FrontendVersion);
26646225b19SZachary Turner     Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor
26746225b19SZachary Turner         << '.' << Compile3.VersionFrontendBuild << '.'
26846225b19SZachary Turner         << Compile3.VersionFrontendQFE;
269aaad5744SZachary Turner   }
270aaad5744SZachary Turner   std::string BackendVersion;
271aaad5744SZachary Turner   {
272aaad5744SZachary Turner     raw_string_ostream Out(BackendVersion);
27346225b19SZachary Turner     Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor
27446225b19SZachary Turner         << '.' << Compile3.VersionBackendBuild << '.'
27546225b19SZachary Turner         << Compile3.VersionBackendQFE;
276aaad5744SZachary Turner   }
277aaad5744SZachary Turner   W.printString("FrontendVersion", FrontendVersion);
278aaad5744SZachary Turner   W.printString("BackendVersion", BackendVersion);
279aaad5744SZachary Turner   W.printString("VersionName", Compile3.Version);
2800d840744SZachary Turner   return Error::success();
281aaad5744SZachary Turner }
282aaad5744SZachary Turner 
2830d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
284aaad5744SZachary Turner                                            ConstantSym &Constant) {
285aaad5744SZachary Turner   DictScope S(W, "Constant");
286aaad5744SZachary Turner 
287629cb7d8SZachary Turner   printTypeIndex("Type", Constant.Type);
288aaad5744SZachary Turner   W.printNumber("Value", Constant.Value);
289aaad5744SZachary Turner   W.printString("Name", Constant.Name);
2900d840744SZachary Turner   return Error::success();
291aaad5744SZachary Turner }
292aaad5744SZachary Turner 
2930d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
294aaad5744SZachary Turner   DictScope S(W, "DataSym");
295aaad5744SZachary Turner 
2960d840744SZachary Turner   W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames());
297aaad5744SZachary Turner   StringRef LinkageName;
298aaad5744SZachary Turner   if (ObjDelegate) {
299aaad5744SZachary Turner     ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
30046225b19SZachary Turner                                      Data.DataOffset, &LinkageName);
301aaad5744SZachary Turner   }
302629cb7d8SZachary Turner   printTypeIndex("Type", Data.Type);
303aaad5744SZachary Turner   W.printString("DisplayName", Data.Name);
304aaad5744SZachary Turner   if (!LinkageName.empty())
305aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
3060d840744SZachary Turner   return Error::success();
307aaad5744SZachary Turner }
308aaad5744SZachary Turner 
3090d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3100d840744SZachary Turner     CVSymbol &CVR,
311aaad5744SZachary Turner     DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
312aaad5744SZachary Turner   DictScope S(W, "DefRangeFramePointerRelFullScope");
31346225b19SZachary Turner   W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
3140d840744SZachary Turner   return Error::success();
315aaad5744SZachary Turner }
316aaad5744SZachary Turner 
3170d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3180d840744SZachary Turner     CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
319aaad5744SZachary Turner   DictScope S(W, "DefRangeFramePointerRel");
320aaad5744SZachary Turner 
32146225b19SZachary Turner   W.printNumber("Offset", DefRangeFramePointerRel.Offset);
32246225b19SZachary Turner   printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
323aaad5744SZachary Turner                               DefRangeFramePointerRel.getRelocationOffset());
324aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
3250d840744SZachary Turner   return Error::success();
326aaad5744SZachary Turner }
327aaad5744SZachary Turner 
3280d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3290d840744SZachary Turner     CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
330aaad5744SZachary Turner   DictScope S(W, "DefRangeRegisterRel");
331aaad5744SZachary Turner 
33246225b19SZachary Turner   W.printNumber("BaseRegister", DefRangeRegisterRel.Hdr.Register);
333aaad5744SZachary Turner   W.printBoolean("HasSpilledUDTMember",
334aaad5744SZachary Turner                  DefRangeRegisterRel.hasSpilledUDTMember());
335aaad5744SZachary Turner   W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
33646225b19SZachary Turner   W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);
33746225b19SZachary Turner   printLocalVariableAddrRange(DefRangeRegisterRel.Range,
338aaad5744SZachary Turner                               DefRangeRegisterRel.getRelocationOffset());
339aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
3400d840744SZachary Turner   return Error::success();
341aaad5744SZachary Turner }
342aaad5744SZachary Turner 
3430d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3440d840744SZachary Turner     CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
345aaad5744SZachary Turner   DictScope S(W, "DefRangeRegister");
346aaad5744SZachary Turner 
34746225b19SZachary Turner   W.printNumber("Register", DefRangeRegister.Hdr.Register);
34846225b19SZachary Turner   W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
34946225b19SZachary Turner   printLocalVariableAddrRange(DefRangeRegister.Range,
350aaad5744SZachary Turner                               DefRangeRegister.getRelocationOffset());
351aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeRegister.Gaps);
3520d840744SZachary Turner   return Error::success();
353aaad5744SZachary Turner }
354aaad5744SZachary Turner 
3550d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3560d840744SZachary Turner     CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
357aaad5744SZachary Turner   DictScope S(W, "DefRangeSubfieldRegister");
358aaad5744SZachary Turner 
35946225b19SZachary Turner   W.printNumber("Register", DefRangeSubfieldRegister.Hdr.Register);
36046225b19SZachary Turner   W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
36146225b19SZachary Turner   W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
36246225b19SZachary Turner   printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
363aaad5744SZachary Turner                               DefRangeSubfieldRegister.getRelocationOffset());
364aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
3650d840744SZachary Turner   return Error::success();
366aaad5744SZachary Turner }
367aaad5744SZachary Turner 
3680d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3690d840744SZachary Turner     CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
370aaad5744SZachary Turner   DictScope S(W, "DefRangeSubfield");
371aaad5744SZachary Turner 
372aaad5744SZachary Turner   if (ObjDelegate) {
373*2d5c2cd3SZachary Turner     StringTableRef Strings = ObjDelegate->getStringTable();
374*2d5c2cd3SZachary Turner     auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
375*2d5c2cd3SZachary Turner     if (!ExpectedProgram) {
376*2d5c2cd3SZachary Turner       consumeError(ExpectedProgram.takeError());
3770d840744SZachary Turner       return llvm::make_error<CodeViewError>(
3780d840744SZachary Turner           "String table offset outside of bounds of String Table!");
379*2d5c2cd3SZachary Turner     }
380*2d5c2cd3SZachary Turner     W.printString("Program", *ExpectedProgram);
381aaad5744SZachary Turner   }
38246225b19SZachary Turner   W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
38346225b19SZachary Turner   printLocalVariableAddrRange(DefRangeSubfield.Range,
384aaad5744SZachary Turner                               DefRangeSubfield.getRelocationOffset());
385aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeSubfield.Gaps);
3860d840744SZachary Turner   return Error::success();
387aaad5744SZachary Turner }
388aaad5744SZachary Turner 
3890d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
390aaad5744SZachary Turner                                            DefRangeSym &DefRange) {
391aaad5744SZachary Turner   DictScope S(W, "DefRange");
392aaad5744SZachary Turner 
393aaad5744SZachary Turner   if (ObjDelegate) {
394*2d5c2cd3SZachary Turner     StringTableRef Strings = ObjDelegate->getStringTable();
395*2d5c2cd3SZachary Turner     auto ExpectedProgram = Strings.getString(DefRange.Program);
396*2d5c2cd3SZachary Turner     if (!ExpectedProgram) {
397*2d5c2cd3SZachary Turner       consumeError(ExpectedProgram.takeError());
3980d840744SZachary Turner       return llvm::make_error<CodeViewError>(
3990d840744SZachary Turner           "String table offset outside of bounds of String Table!");
400*2d5c2cd3SZachary Turner     }
401*2d5c2cd3SZachary Turner     W.printString("Program", *ExpectedProgram);
402aaad5744SZachary Turner   }
40346225b19SZachary Turner   printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
404aaad5744SZachary Turner   printLocalVariableAddrGap(DefRange.Gaps);
4050d840744SZachary Turner   return Error::success();
406aaad5744SZachary Turner }
407aaad5744SZachary Turner 
4080d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
409aaad5744SZachary Turner                                            FrameCookieSym &FrameCookie) {
410aaad5744SZachary Turner   DictScope S(W, "FrameCookie");
411aaad5744SZachary Turner 
412aaad5744SZachary Turner   StringRef LinkageName;
413aaad5744SZachary Turner   if (ObjDelegate) {
41446225b19SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset",
41546225b19SZachary Turner                                      FrameCookie.getRelocationOffset(),
41646225b19SZachary Turner                                      FrameCookie.CodeOffset, &LinkageName);
417aaad5744SZachary Turner   }
41846225b19SZachary Turner   W.printHex("Register", FrameCookie.Register);
41946225b19SZachary Turner   W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
42093839cb4SZachary Turner               getFrameCookieKindNames());
42146225b19SZachary Turner   W.printHex("Flags", FrameCookie.Flags);
4220d840744SZachary Turner   return Error::success();
423aaad5744SZachary Turner }
424aaad5744SZachary Turner 
4250d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
426aaad5744SZachary Turner                                            FrameProcSym &FrameProc) {
427aaad5744SZachary Turner   DictScope S(W, "FrameProc");
428aaad5744SZachary Turner 
42946225b19SZachary Turner   W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
43046225b19SZachary Turner   W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
43146225b19SZachary Turner   W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
432aaad5744SZachary Turner   W.printHex("BytesOfCalleeSavedRegisters",
43346225b19SZachary Turner              FrameProc.BytesOfCalleeSavedRegisters);
43446225b19SZachary Turner   W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
435aaad5744SZachary Turner   W.printHex("SectionIdOfExceptionHandler",
43646225b19SZachary Turner              FrameProc.SectionIdOfExceptionHandler);
43746225b19SZachary Turner   W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
43846225b19SZachary Turner                getFrameProcSymFlagNames());
4390d840744SZachary Turner   return Error::success();
440aaad5744SZachary Turner }
441aaad5744SZachary Turner 
4420d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
4430d840744SZachary Turner     CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
444aaad5744SZachary Turner   DictScope S(W, "HeapAllocationSite");
445aaad5744SZachary Turner 
446aaad5744SZachary Turner   StringRef LinkageName;
447aaad5744SZachary Turner   if (ObjDelegate) {
44846225b19SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset",
44946225b19SZachary Turner                                      HeapAllocSite.getRelocationOffset(),
45046225b19SZachary Turner                                      HeapAllocSite.CodeOffset, &LinkageName);
451aaad5744SZachary Turner   }
45246225b19SZachary Turner   W.printHex("Segment", HeapAllocSite.Segment);
45346225b19SZachary Turner   W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
454629cb7d8SZachary Turner   printTypeIndex("Type", HeapAllocSite.Type);
455aaad5744SZachary Turner   if (!LinkageName.empty())
456aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
4570d840744SZachary Turner   return Error::success();
458aaad5744SZachary Turner }
459aaad5744SZachary Turner 
4600d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
461aaad5744SZachary Turner                                            InlineSiteSym &InlineSite) {
462aaad5744SZachary Turner   DictScope S(W, "InlineSite");
463aaad5744SZachary Turner 
46446225b19SZachary Turner   W.printHex("PtrParent", InlineSite.Parent);
46546225b19SZachary Turner   W.printHex("PtrEnd", InlineSite.End);
466629cb7d8SZachary Turner   printTypeIndex("Inlinee", InlineSite.Inlinee);
467aaad5744SZachary Turner 
468aaad5744SZachary Turner   ListScope BinaryAnnotations(W, "BinaryAnnotations");
469aaad5744SZachary Turner   for (auto &Annotation : InlineSite.annotations()) {
470aaad5744SZachary Turner     switch (Annotation.OpCode) {
471aaad5744SZachary Turner     case BinaryAnnotationsOpCode::Invalid:
47242cb87f4SZachary Turner       W.printString("(Annotation Padding)");
47342cb87f4SZachary Turner       break;
474aaad5744SZachary Turner     case BinaryAnnotationsOpCode::CodeOffset:
475aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeOffset:
476aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeLength:
477aaad5744SZachary Turner       W.printHex(Annotation.Name, Annotation.U1);
478aaad5744SZachary Turner       break;
479aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
480aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeLineEndDelta:
481aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeRangeKind:
482aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeColumnStart:
483aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeColumnEnd:
484aaad5744SZachary Turner       W.printNumber(Annotation.Name, Annotation.U1);
485aaad5744SZachary Turner       break;
486aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeLineOffset:
487aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
488aaad5744SZachary Turner       W.printNumber(Annotation.Name, Annotation.S1);
489aaad5744SZachary Turner       break;
490aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeFile:
491aaad5744SZachary Turner       if (ObjDelegate) {
492aaad5744SZachary Turner         W.printHex("ChangeFile",
493aaad5744SZachary Turner                    ObjDelegate->getFileNameForFileOffset(Annotation.U1),
494aaad5744SZachary Turner                    Annotation.U1);
495aaad5744SZachary Turner       } else {
496aaad5744SZachary Turner         W.printHex("ChangeFile", Annotation.U1);
497aaad5744SZachary Turner       }
498aaad5744SZachary Turner 
499aaad5744SZachary Turner       break;
500aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
501aaad5744SZachary Turner       W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
502aaad5744SZachary Turner                     << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
503aaad5744SZachary Turner                     << "}\n";
504aaad5744SZachary Turner       break;
505aaad5744SZachary Turner     }
506aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
507aaad5744SZachary Turner       W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
508aaad5744SZachary Turner                     << W.hex(Annotation.U2)
509aaad5744SZachary Turner                     << ", Length: " << W.hex(Annotation.U1) << "}\n";
510aaad5744SZachary Turner       break;
511aaad5744SZachary Turner     }
512aaad5744SZachary Turner     }
513aaad5744SZachary Turner   }
5140d840744SZachary Turner   return Error::success();
515aaad5744SZachary Turner }
516aaad5744SZachary Turner 
5170d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
5184caa1bf0SZachary Turner                                            RegisterSym &Register) {
5194caa1bf0SZachary Turner   DictScope S(W, "RegisterSym");
52046225b19SZachary Turner   W.printNumber("Type", Register.Index);
52146225b19SZachary Turner   W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames());
5224caa1bf0SZachary Turner   W.printString("Name", Register.Name);
5230d840744SZachary Turner   return Error::success();
5244caa1bf0SZachary Turner }
5254caa1bf0SZachary Turner 
5260d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
5279e33e6f8SZachary Turner   DictScope S(W, "PublicSym");
52846225b19SZachary Turner   W.printNumber("Type", Public.Index);
52946225b19SZachary Turner   W.printNumber("Seg", Public.Segment);
53046225b19SZachary Turner   W.printNumber("Off", Public.Offset);
5319e33e6f8SZachary Turner   W.printString("Name", Public.Name);
5320d840744SZachary Turner   return Error::success();
5339e33e6f8SZachary Turner }
5349e33e6f8SZachary Turner 
5350d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
5369e33e6f8SZachary Turner   DictScope S(W, "ProcRef");
53746225b19SZachary Turner   W.printNumber("SumName", ProcRef.SumName);
53846225b19SZachary Turner   W.printNumber("SymOffset", ProcRef.SymOffset);
53946225b19SZachary Turner   W.printNumber("Mod", ProcRef.Module);
5409e33e6f8SZachary Turner   W.printString("Name", ProcRef.Name);
5410d840744SZachary Turner   return Error::success();
5429e33e6f8SZachary Turner }
5439e33e6f8SZachary Turner 
5440d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
545aaad5744SZachary Turner   DictScope S(W, "Label");
546aaad5744SZachary Turner 
547aaad5744SZachary Turner   StringRef LinkageName;
548aaad5744SZachary Turner   if (ObjDelegate) {
549aaad5744SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
55046225b19SZachary Turner                                      Label.CodeOffset, &LinkageName);
551aaad5744SZachary Turner   }
55246225b19SZachary Turner   W.printHex("Segment", Label.Segment);
55346225b19SZachary Turner   W.printHex("Flags", uint8_t(Label.Flags));
55446225b19SZachary Turner   W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
555aaad5744SZachary Turner   W.printString("DisplayName", Label.Name);
556aaad5744SZachary Turner   if (!LinkageName.empty())
557aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
5580d840744SZachary Turner   return Error::success();
559aaad5744SZachary Turner }
560aaad5744SZachary Turner 
5610d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
562aaad5744SZachary Turner   DictScope S(W, "Local");
563aaad5744SZachary Turner 
564629cb7d8SZachary Turner   printTypeIndex("Type", Local.Type);
56546225b19SZachary Turner   W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
566aaad5744SZachary Turner   W.printString("VarName", Local.Name);
5670d840744SZachary Turner   return Error::success();
568aaad5744SZachary Turner }
569aaad5744SZachary Turner 
5700d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
571aaad5744SZachary Turner   DictScope S(W, "ObjectName");
572aaad5744SZachary Turner 
57346225b19SZachary Turner   W.printHex("Signature", ObjName.Signature);
574aaad5744SZachary Turner   W.printString("ObjectName", ObjName.Name);
5750d840744SZachary Turner   return Error::success();
576aaad5744SZachary Turner }
577aaad5744SZachary Turner 
5780d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
579aaad5744SZachary Turner   DictScope S(W, "ProcStart");
580aaad5744SZachary Turner 
581aaad5744SZachary Turner   if (InFunctionScope)
5820d840744SZachary Turner     return llvm::make_error<CodeViewError>(
5830d840744SZachary Turner         "Visiting a ProcSym while inside function scope!");
584aaad5744SZachary Turner 
585aaad5744SZachary Turner   InFunctionScope = true;
586aaad5744SZachary Turner 
587aaad5744SZachary Turner   StringRef LinkageName;
5880d840744SZachary Turner   W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames());
58946225b19SZachary Turner   W.printHex("PtrParent", Proc.Parent);
59046225b19SZachary Turner   W.printHex("PtrEnd", Proc.End);
59146225b19SZachary Turner   W.printHex("PtrNext", Proc.Next);
59246225b19SZachary Turner   W.printHex("CodeSize", Proc.CodeSize);
59346225b19SZachary Turner   W.printHex("DbgStart", Proc.DbgStart);
59446225b19SZachary Turner   W.printHex("DbgEnd", Proc.DbgEnd);
595629cb7d8SZachary Turner   printTypeIndex("FunctionType", Proc.FunctionType);
596aaad5744SZachary Turner   if (ObjDelegate) {
597aaad5744SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
59846225b19SZachary Turner                                      Proc.CodeOffset, &LinkageName);
599aaad5744SZachary Turner   }
60046225b19SZachary Turner   W.printHex("Segment", Proc.Segment);
60146225b19SZachary Turner   W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
60293839cb4SZachary Turner                getProcSymFlagNames());
603aaad5744SZachary Turner   W.printString("DisplayName", Proc.Name);
604aaad5744SZachary Turner   if (!LinkageName.empty())
605aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
6060d840744SZachary Turner   return Error::success();
607aaad5744SZachary Turner }
608aaad5744SZachary Turner 
6090d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
610aaad5744SZachary Turner                                            ScopeEndSym &ScopeEnd) {
6110d840744SZachary Turner   if (CVR.kind() == SymbolKind::S_END)
612cac29ae0SZachary Turner     DictScope S(W, "BlockEnd");
6130d840744SZachary Turner   else if (CVR.kind() == SymbolKind::S_PROC_ID_END)
614cac29ae0SZachary Turner     DictScope S(W, "ProcEnd");
6150d840744SZachary Turner   else if (CVR.kind() == SymbolKind::S_INLINESITE_END)
616aaad5744SZachary Turner     DictScope S(W, "InlineSiteEnd");
617aaad5744SZachary Turner 
618aaad5744SZachary Turner   InFunctionScope = false;
6190d840744SZachary Turner   return Error::success();
620aaad5744SZachary Turner }
621aaad5744SZachary Turner 
6220d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
6230d840744SZachary Turner   ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
624aaad5744SZachary Turner   for (auto FuncID : Caller.Indices)
625629cb7d8SZachary Turner     printTypeIndex("FuncID", FuncID);
6260d840744SZachary Turner   return Error::success();
627aaad5744SZachary Turner }
628aaad5744SZachary Turner 
6290d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
630aaad5744SZachary Turner                                            RegRelativeSym &RegRel) {
631aaad5744SZachary Turner   DictScope S(W, "RegRelativeSym");
632aaad5744SZachary Turner 
63346225b19SZachary Turner   W.printHex("Offset", RegRel.Offset);
634629cb7d8SZachary Turner   printTypeIndex("Type", RegRel.Type);
63546225b19SZachary Turner   W.printHex("Register", RegRel.Register);
636aaad5744SZachary Turner   W.printString("VarName", RegRel.Name);
6370d840744SZachary Turner   return Error::success();
638aaad5744SZachary Turner }
639aaad5744SZachary Turner 
6400d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
641aaad5744SZachary Turner                                            ThreadLocalDataSym &Data) {
642aaad5744SZachary Turner   DictScope S(W, "ThreadLocalDataSym");
643aaad5744SZachary Turner 
644aaad5744SZachary Turner   StringRef LinkageName;
645aaad5744SZachary Turner   if (ObjDelegate) {
646aaad5744SZachary Turner     ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
64746225b19SZachary Turner                                      Data.DataOffset, &LinkageName);
648aaad5744SZachary Turner   }
649629cb7d8SZachary Turner   printTypeIndex("Type", Data.Type);
650aaad5744SZachary Turner   W.printString("DisplayName", Data.Name);
651aaad5744SZachary Turner   if (!LinkageName.empty())
652aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
6530d840744SZachary Turner   return Error::success();
654aaad5744SZachary Turner }
655aaad5744SZachary Turner 
6560d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
657aaad5744SZachary Turner   DictScope S(W, "UDT");
658629cb7d8SZachary Turner   printTypeIndex("Type", UDT.Type);
659aaad5744SZachary Turner   W.printString("UDTName", UDT.Name);
6600d840744SZachary Turner   return Error::success();
661aaad5744SZachary Turner }
662aaad5744SZachary Turner 
6630d840744SZachary Turner Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
664aaad5744SZachary Turner   DictScope S(W, "UnknownSym");
6650d840744SZachary Turner   W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames());
6660d840744SZachary Turner   W.printNumber("Length", CVR.length());
6670d840744SZachary Turner   return Error::success();
668aaad5744SZachary Turner }
669aaad5744SZachary Turner 
6700d840744SZachary Turner Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
6710d840744SZachary Turner   SymbolVisitorCallbackPipeline Pipeline;
6720d840744SZachary Turner   SymbolDeserializer Deserializer(ObjDelegate.get());
673629cb7d8SZachary Turner   CVSymbolDumperImpl Dumper(TypeDB, ObjDelegate.get(), W, PrintRecordBytes);
6740d840744SZachary Turner 
6750d840744SZachary Turner   Pipeline.addCallbackToPipeline(Deserializer);
6760d840744SZachary Turner   Pipeline.addCallbackToPipeline(Dumper);
6770d840744SZachary Turner   CVSymbolVisitor Visitor(Pipeline);
6780d840744SZachary Turner   return Visitor.visitSymbolRecord(Record);
679aaad5744SZachary Turner }
680aaad5744SZachary Turner 
6810d840744SZachary Turner Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
6820d840744SZachary Turner   SymbolVisitorCallbackPipeline Pipeline;
6830d840744SZachary Turner   SymbolDeserializer Deserializer(ObjDelegate.get());
684629cb7d8SZachary Turner   CVSymbolDumperImpl Dumper(TypeDB, ObjDelegate.get(), W, PrintRecordBytes);
6850d840744SZachary Turner 
6860d840744SZachary Turner   Pipeline.addCallbackToPipeline(Deserializer);
6870d840744SZachary Turner   Pipeline.addCallbackToPipeline(Dumper);
6880d840744SZachary Turner   CVSymbolVisitor Visitor(Pipeline);
6890d840744SZachary Turner   return Visitor.visitSymbolStream(Symbols);
690aaad5744SZachary Turner }
691