]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
Vendor import of llvm trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / lib / DebugInfo / CodeView / TypeDumpVisitor.cpp
1 //===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===//
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 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
11
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
14 #include "llvm/DebugInfo/CodeView/Formatters.h"
15 #include "llvm/DebugInfo/CodeView/TypeCollection.h"
16 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
17 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
18 #include "llvm/Support/FormatVariadic.h"
19 #include "llvm/Support/ScopedPrinter.h"
20
21 using namespace llvm;
22 using namespace llvm::codeview;
23
24 static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
25 #define CV_TYPE(enum, val) {#enum, enum},
26 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
27 };
28
29 #define ENUM_ENTRY(enum_class, enum)                                           \
30   { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
31
32 static const EnumEntry<uint16_t> ClassOptionNames[] = {
33     ENUM_ENTRY(ClassOptions, Packed),
34     ENUM_ENTRY(ClassOptions, HasConstructorOrDestructor),
35     ENUM_ENTRY(ClassOptions, HasOverloadedOperator),
36     ENUM_ENTRY(ClassOptions, Nested),
37     ENUM_ENTRY(ClassOptions, ContainsNestedClass),
38     ENUM_ENTRY(ClassOptions, HasOverloadedAssignmentOperator),
39     ENUM_ENTRY(ClassOptions, HasConversionOperator),
40     ENUM_ENTRY(ClassOptions, ForwardReference),
41     ENUM_ENTRY(ClassOptions, Scoped),
42     ENUM_ENTRY(ClassOptions, HasUniqueName),
43     ENUM_ENTRY(ClassOptions, Sealed),
44     ENUM_ENTRY(ClassOptions, Intrinsic),
45 };
46
47 static const EnumEntry<uint8_t> MemberAccessNames[] = {
48     ENUM_ENTRY(MemberAccess, None), ENUM_ENTRY(MemberAccess, Private),
49     ENUM_ENTRY(MemberAccess, Protected), ENUM_ENTRY(MemberAccess, Public),
50 };
51
52 static const EnumEntry<uint16_t> MethodOptionNames[] = {
53     ENUM_ENTRY(MethodOptions, Pseudo),
54     ENUM_ENTRY(MethodOptions, NoInherit),
55     ENUM_ENTRY(MethodOptions, NoConstruct),
56     ENUM_ENTRY(MethodOptions, CompilerGenerated),
57     ENUM_ENTRY(MethodOptions, Sealed),
58 };
59
60 static const EnumEntry<uint16_t> MemberKindNames[] = {
61     ENUM_ENTRY(MethodKind, Vanilla),
62     ENUM_ENTRY(MethodKind, Virtual),
63     ENUM_ENTRY(MethodKind, Static),
64     ENUM_ENTRY(MethodKind, Friend),
65     ENUM_ENTRY(MethodKind, IntroducingVirtual),
66     ENUM_ENTRY(MethodKind, PureVirtual),
67     ENUM_ENTRY(MethodKind, PureIntroducingVirtual),
68 };
69
70 static const EnumEntry<uint8_t> PtrKindNames[] = {
71     ENUM_ENTRY(PointerKind, Near16),
72     ENUM_ENTRY(PointerKind, Far16),
73     ENUM_ENTRY(PointerKind, Huge16),
74     ENUM_ENTRY(PointerKind, BasedOnSegment),
75     ENUM_ENTRY(PointerKind, BasedOnValue),
76     ENUM_ENTRY(PointerKind, BasedOnSegmentValue),
77     ENUM_ENTRY(PointerKind, BasedOnAddress),
78     ENUM_ENTRY(PointerKind, BasedOnSegmentAddress),
79     ENUM_ENTRY(PointerKind, BasedOnType),
80     ENUM_ENTRY(PointerKind, BasedOnSelf),
81     ENUM_ENTRY(PointerKind, Near32),
82     ENUM_ENTRY(PointerKind, Far32),
83     ENUM_ENTRY(PointerKind, Near64),
84 };
85
86 static const EnumEntry<uint8_t> PtrModeNames[] = {
87     ENUM_ENTRY(PointerMode, Pointer),
88     ENUM_ENTRY(PointerMode, LValueReference),
89     ENUM_ENTRY(PointerMode, PointerToDataMember),
90     ENUM_ENTRY(PointerMode, PointerToMemberFunction),
91     ENUM_ENTRY(PointerMode, RValueReference),
92 };
93
94 static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
95     ENUM_ENTRY(PointerToMemberRepresentation, Unknown),
96     ENUM_ENTRY(PointerToMemberRepresentation, SingleInheritanceData),
97     ENUM_ENTRY(PointerToMemberRepresentation, MultipleInheritanceData),
98     ENUM_ENTRY(PointerToMemberRepresentation, VirtualInheritanceData),
99     ENUM_ENTRY(PointerToMemberRepresentation, GeneralData),
100     ENUM_ENTRY(PointerToMemberRepresentation, SingleInheritanceFunction),
101     ENUM_ENTRY(PointerToMemberRepresentation, MultipleInheritanceFunction),
102     ENUM_ENTRY(PointerToMemberRepresentation, VirtualInheritanceFunction),
103     ENUM_ENTRY(PointerToMemberRepresentation, GeneralFunction),
104 };
105
106 static const EnumEntry<uint16_t> TypeModifierNames[] = {
107     ENUM_ENTRY(ModifierOptions, Const), ENUM_ENTRY(ModifierOptions, Volatile),
108     ENUM_ENTRY(ModifierOptions, Unaligned),
109 };
110
111 static const EnumEntry<uint8_t> CallingConventions[] = {
112     ENUM_ENTRY(CallingConvention, NearC),
113     ENUM_ENTRY(CallingConvention, FarC),
114     ENUM_ENTRY(CallingConvention, NearPascal),
115     ENUM_ENTRY(CallingConvention, FarPascal),
116     ENUM_ENTRY(CallingConvention, NearFast),
117     ENUM_ENTRY(CallingConvention, FarFast),
118     ENUM_ENTRY(CallingConvention, NearStdCall),
119     ENUM_ENTRY(CallingConvention, FarStdCall),
120     ENUM_ENTRY(CallingConvention, NearSysCall),
121     ENUM_ENTRY(CallingConvention, FarSysCall),
122     ENUM_ENTRY(CallingConvention, ThisCall),
123     ENUM_ENTRY(CallingConvention, MipsCall),
124     ENUM_ENTRY(CallingConvention, Generic),
125     ENUM_ENTRY(CallingConvention, AlphaCall),
126     ENUM_ENTRY(CallingConvention, PpcCall),
127     ENUM_ENTRY(CallingConvention, SHCall),
128     ENUM_ENTRY(CallingConvention, ArmCall),
129     ENUM_ENTRY(CallingConvention, AM33Call),
130     ENUM_ENTRY(CallingConvention, TriCall),
131     ENUM_ENTRY(CallingConvention, SH5Call),
132     ENUM_ENTRY(CallingConvention, M32RCall),
133     ENUM_ENTRY(CallingConvention, ClrCall),
134     ENUM_ENTRY(CallingConvention, Inline),
135     ENUM_ENTRY(CallingConvention, NearVector),
136 };
137
138 static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
139     ENUM_ENTRY(FunctionOptions, CxxReturnUdt),
140     ENUM_ENTRY(FunctionOptions, Constructor),
141     ENUM_ENTRY(FunctionOptions, ConstructorWithVirtualBases),
142 };
143
144 static const EnumEntry<uint16_t> LabelTypeEnum[] = {
145     ENUM_ENTRY(LabelType, Near), ENUM_ENTRY(LabelType, Far),
146 };
147
148 #undef ENUM_ENTRY
149
150 static StringRef getLeafTypeName(TypeLeafKind LT) {
151   switch (LT) {
152 #define TYPE_RECORD(ename, value, name)                                        \
153   case ename:                                                                  \
154     return #name;
155 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
156   default:
157     break;
158   }
159   return "UnknownLeaf";
160 }
161
162 void TypeDumpVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
163   codeview::printTypeIndex(*W, FieldName, TI, TpiTypes);
164 }
165
166 void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
167   codeview::printTypeIndex(*W, FieldName, TI, getSourceTypes());
168 }
169
170 Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
171   return visitTypeBegin(Record, TypeIndex::fromArrayIndex(TpiTypes.size()));
172 }
173
174 Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
175   W->startLine() << getLeafTypeName(Record.Type);
176   W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
177   W->getOStream() << " {\n";
178   W->indent();
179   W->printEnum("TypeLeafKind", unsigned(Record.Type),
180                makeArrayRef(LeafTypeNames));
181   return Error::success();
182 }
183
184 Error TypeDumpVisitor::visitTypeEnd(CVType &Record) {
185   if (PrintRecordBytes)
186     W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));
187
188   W->unindent();
189   W->startLine() << "}\n";
190   return Error::success();
191 }
192
193 Error TypeDumpVisitor::visitMemberBegin(CVMemberRecord &Record) {
194   W->startLine() << getLeafTypeName(Record.Kind);
195   W->getOStream() << " {\n";
196   W->indent();
197   W->printEnum("TypeLeafKind", unsigned(Record.Kind),
198                makeArrayRef(LeafTypeNames));
199   return Error::success();
200 }
201
202 Error TypeDumpVisitor::visitMemberEnd(CVMemberRecord &Record) {
203   if (PrintRecordBytes)
204     W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
205
206   W->unindent();
207   W->startLine() << "}\n";
208   return Error::success();
209 }
210
211 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
212                                         FieldListRecord &FieldList) {
213   if (auto EC = codeview::visitMemberRecordStream(FieldList.Data, *this))
214     return EC;
215
216   return Error::success();
217 }
218
219 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringIdRecord &String) {
220   printItemIndex("Id", String.getId());
221   W->printString("StringData", String.getString());
222   return Error::success();
223 }
224
225 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
226   auto Indices = Args.getIndices();
227   uint32_t Size = Indices.size();
228   W->printNumber("NumArgs", Size);
229   ListScope Arguments(*W, "Arguments");
230   for (uint32_t I = 0; I < Size; ++I) {
231     printTypeIndex("ArgType", Indices[I]);
232   }
233   return Error::success();
234 }
235
236 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringListRecord &Strs) {
237   auto Indices = Strs.getIndices();
238   uint32_t Size = Indices.size();
239   W->printNumber("NumStrings", Size);
240   ListScope Arguments(*W, "Strings");
241   for (uint32_t I = 0; I < Size; ++I) {
242     printItemIndex("String", Indices[I]);
243   }
244   return Error::success();
245 }
246
247 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
248   uint16_t Props = static_cast<uint16_t>(Class.getOptions());
249   W->printNumber("MemberCount", Class.getMemberCount());
250   W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
251   printTypeIndex("FieldList", Class.getFieldList());
252   printTypeIndex("DerivedFrom", Class.getDerivationList());
253   printTypeIndex("VShape", Class.getVTableShape());
254   W->printNumber("SizeOf", Class.getSize());
255   W->printString("Name", Class.getName());
256   if (Props & uint16_t(ClassOptions::HasUniqueName))
257     W->printString("LinkageName", Class.getUniqueName());
258   return Error::success();
259 }
260
261 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
262   uint16_t Props = static_cast<uint16_t>(Union.getOptions());
263   W->printNumber("MemberCount", Union.getMemberCount());
264   W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
265   printTypeIndex("FieldList", Union.getFieldList());
266   W->printNumber("SizeOf", Union.getSize());
267   W->printString("Name", Union.getName());
268   if (Props & uint16_t(ClassOptions::HasUniqueName))
269     W->printString("LinkageName", Union.getUniqueName());
270   return Error::success();
271 }
272
273 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
274   uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
275   W->printNumber("NumEnumerators", Enum.getMemberCount());
276   W->printFlags("Properties", uint16_t(Enum.getOptions()),
277                 makeArrayRef(ClassOptionNames));
278   printTypeIndex("UnderlyingType", Enum.getUnderlyingType());
279   printTypeIndex("FieldListType", Enum.getFieldList());
280   W->printString("Name", Enum.getName());
281   if (Props & uint16_t(ClassOptions::HasUniqueName))
282     W->printString("LinkageName", Enum.getUniqueName());
283   return Error::success();
284 }
285
286 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
287   printTypeIndex("ElementType", AT.getElementType());
288   printTypeIndex("IndexType", AT.getIndexType());
289   W->printNumber("SizeOf", AT.getSize());
290   W->printString("Name", AT.getName());
291   return Error::success();
292 }
293
294 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
295   printTypeIndex("CompleteClass", VFT.getCompleteClass());
296   printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
297   W->printHex("VFPtrOffset", VFT.getVFPtrOffset());
298   W->printString("VFTableName", VFT.getName());
299   for (auto N : VFT.getMethodNames())
300     W->printString("MethodName", N);
301   return Error::success();
302 }
303
304 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
305   printTypeIndex("ClassType", Id.getClassType());
306   printTypeIndex("FunctionType", Id.getFunctionType());
307   W->printString("Name", Id.getName());
308   return Error::success();
309 }
310
311 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
312   printTypeIndex("ReturnType", Proc.getReturnType());
313   W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
314                makeArrayRef(CallingConventions));
315   W->printFlags("FunctionOptions", uint8_t(Proc.getOptions()),
316                 makeArrayRef(FunctionOptionEnum));
317   W->printNumber("NumParameters", Proc.getParameterCount());
318   printTypeIndex("ArgListType", Proc.getArgumentList());
319   return Error::success();
320 }
321
322 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFunctionRecord &MF) {
323   printTypeIndex("ReturnType", MF.getReturnType());
324   printTypeIndex("ClassType", MF.getClassType());
325   printTypeIndex("ThisType", MF.getThisType());
326   W->printEnum("CallingConvention", uint8_t(MF.getCallConv()),
327                makeArrayRef(CallingConventions));
328   W->printFlags("FunctionOptions", uint8_t(MF.getOptions()),
329                 makeArrayRef(FunctionOptionEnum));
330   W->printNumber("NumParameters", MF.getParameterCount());
331   printTypeIndex("ArgListType", MF.getArgumentList());
332   W->printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
333   return Error::success();
334 }
335
336 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
337                                         MethodOverloadListRecord &MethodList) {
338   for (auto &M : MethodList.getMethods()) {
339     ListScope S(*W, "Method");
340     printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions());
341     printTypeIndex("Type", M.getType());
342     if (M.isIntroducingVirtual())
343       W->printHex("VFTableOffset", M.getVFTableOffset());
344   }
345   return Error::success();
346 }
347
348 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
349   printItemIndex("ParentScope", Func.getParentScope());
350   printTypeIndex("FunctionType", Func.getFunctionType());
351   W->printString("Name", Func.getName());
352   return Error::success();
353 }
354
355 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
356   W->printString("Guid", formatv("{0}", TS.getGuid()).str());
357   W->printNumber("Age", TS.getAge());
358   W->printString("Name", TS.getName());
359   return Error::success();
360 }
361
362 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
363   printTypeIndex("PointeeType", Ptr.getReferentType());
364   W->printEnum("PtrType", unsigned(Ptr.getPointerKind()),
365                makeArrayRef(PtrKindNames));
366   W->printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames));
367
368   W->printNumber("IsFlat", Ptr.isFlat());
369   W->printNumber("IsConst", Ptr.isConst());
370   W->printNumber("IsVolatile", Ptr.isVolatile());
371   W->printNumber("IsUnaligned", Ptr.isUnaligned());
372   W->printNumber("IsRestrict", Ptr.isRestrict());
373   W->printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
374   W->printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
375   W->printNumber("SizeOf", Ptr.getSize());
376
377   if (Ptr.isPointerToMember()) {
378     const MemberPointerInfo &MI = Ptr.getMemberInfo();
379
380     printTypeIndex("ClassType", MI.getContainingType());
381     W->printEnum("Representation", uint16_t(MI.getRepresentation()),
382                  makeArrayRef(PtrMemberRepNames));
383   }
384
385   return Error::success();
386 }
387
388 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
389   uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
390   printTypeIndex("ModifiedType", Mod.getModifiedType());
391   W->printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
392
393   return Error::success();
394 }
395
396 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BitFieldRecord &BitField) {
397   printTypeIndex("Type", BitField.getType());
398   W->printNumber("BitSize", BitField.getBitSize());
399   W->printNumber("BitOffset", BitField.getBitOffset());
400   return Error::success();
401 }
402
403 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
404                                         VFTableShapeRecord &Shape) {
405   W->printNumber("VFEntryCount", Shape.getEntryCount());
406   return Error::success();
407 }
408
409 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
410                                         UdtSourceLineRecord &Line) {
411   printTypeIndex("UDT", Line.getUDT());
412   printItemIndex("SourceFile", Line.getSourceFile());
413   W->printNumber("LineNumber", Line.getLineNumber());
414   return Error::success();
415 }
416
417 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
418                                         UdtModSourceLineRecord &Line) {
419   printTypeIndex("UDT", Line.getUDT());
420   printItemIndex("SourceFile", Line.getSourceFile());
421   W->printNumber("LineNumber", Line.getLineNumber());
422   W->printNumber("Module", Line.getModule());
423   return Error::success();
424 }
425
426 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &Args) {
427   W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
428
429   ListScope Arguments(*W, "Arguments");
430   for (auto Arg : Args.getArgs()) {
431     printItemIndex("ArgType", Arg);
432   }
433   return Error::success();
434 }
435
436 void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs) {
437   return printMemberAttributes(Attrs.getAccess(), Attrs.getMethodKind(),
438                                Attrs.getFlags());
439 }
440
441 void TypeDumpVisitor::printMemberAttributes(MemberAccess Access,
442                                             MethodKind Kind,
443                                             MethodOptions Options) {
444   W->printEnum("AccessSpecifier", uint8_t(Access),
445                makeArrayRef(MemberAccessNames));
446   // Data members will be vanilla. Don't try to print a method kind for them.
447   if (Kind != MethodKind::Vanilla)
448     W->printEnum("MethodKind", unsigned(Kind), makeArrayRef(MemberKindNames));
449   if (Options != MethodOptions::None) {
450     W->printFlags("MethodOptions", unsigned(Options),
451                   makeArrayRef(MethodOptionNames));
452   }
453 }
454
455 Error TypeDumpVisitor::visitUnknownMember(CVMemberRecord &Record) {
456   W->printHex("UnknownMember", unsigned(Record.Kind));
457   return Error::success();
458 }
459
460 Error TypeDumpVisitor::visitUnknownType(CVType &Record) {
461   W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames));
462   W->printNumber("Length", uint32_t(Record.content().size()));
463   return Error::success();
464 }
465
466 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
467                                         NestedTypeRecord &Nested) {
468   printTypeIndex("Type", Nested.getNestedType());
469   W->printString("Name", Nested.getName());
470   return Error::success();
471 }
472
473 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
474                                         OneMethodRecord &Method) {
475   MethodKind K = Method.getMethodKind();
476   printMemberAttributes(Method.getAccess(), K, Method.getOptions());
477   printTypeIndex("Type", Method.getType());
478   // If virtual, then read the vftable offset.
479   if (Method.isIntroducingVirtual())
480     W->printHex("VFTableOffset", Method.getVFTableOffset());
481   W->printString("Name", Method.getName());
482   return Error::success();
483 }
484
485 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
486                                         OverloadedMethodRecord &Method) {
487   W->printHex("MethodCount", Method.getNumOverloads());
488   printTypeIndex("MethodListIndex", Method.getMethodList());
489   W->printString("Name", Method.getName());
490   return Error::success();
491 }
492
493 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
494                                         DataMemberRecord &Field) {
495   printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
496                         MethodOptions::None);
497   printTypeIndex("Type", Field.getType());
498   W->printHex("FieldOffset", Field.getFieldOffset());
499   W->printString("Name", Field.getName());
500   return Error::success();
501 }
502
503 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
504                                         StaticDataMemberRecord &Field) {
505   printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
506                         MethodOptions::None);
507   printTypeIndex("Type", Field.getType());
508   W->printString("Name", Field.getName());
509   return Error::success();
510 }
511
512 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
513                                         VFPtrRecord &VFTable) {
514   printTypeIndex("Type", VFTable.getType());
515   return Error::success();
516 }
517
518 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
519                                         EnumeratorRecord &Enum) {
520   printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
521                         MethodOptions::None);
522   W->printNumber("EnumValue", Enum.getValue());
523   W->printString("Name", Enum.getName());
524   return Error::success();
525 }
526
527 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
528                                         BaseClassRecord &Base) {
529   printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
530                         MethodOptions::None);
531   printTypeIndex("BaseType", Base.getBaseType());
532   W->printHex("BaseOffset", Base.getBaseOffset());
533   return Error::success();
534 }
535
536 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
537                                         VirtualBaseClassRecord &Base) {
538   printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
539                         MethodOptions::None);
540   printTypeIndex("BaseType", Base.getBaseType());
541   printTypeIndex("VBPtrType", Base.getVBPtrType());
542   W->printHex("VBPtrOffset", Base.getVBPtrOffset());
543   W->printHex("VBTableIndex", Base.getVTableIndex());
544   return Error::success();
545 }
546
547 Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
548                                         ListContinuationRecord &Cont) {
549   printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
550   return Error::success();
551 }
552
553 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) {
554   W->printEnum("Mode", uint16_t(LR.Mode), makeArrayRef(LabelTypeEnum));
555   return Error::success();
556 }
557
558 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
559                                         PrecompRecord &Precomp) {
560   W->printHex("StartIndex", Precomp.getStartTypeIndex());
561   W->printHex("Count", Precomp.getTypesCount());
562   W->printHex("Signature", Precomp.getSignature());
563   W->printString("PrecompFile", Precomp.getPrecompFilePath());
564   return Error::success();
565 }
566
567 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
568                                         EndPrecompRecord &EndPrecomp) {
569   W->printHex("Signature", EndPrecomp.getSignature());
570   return Error::success();
571 }