1 //===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
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"
22 using namespace llvm::codeview
;
24 static const EnumEntry
<TypeLeafKind
> LeafTypeNames
[] = {
25 #define CV_TYPE(enum, val) {#enum, enum},
26 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
29 #define ENUM_ENTRY(enum_class, enum) \
30 { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
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
),
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
),
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
),
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
),
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
),
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
),
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
),
106 static const EnumEntry
<uint16_t> TypeModifierNames
[] = {
107 ENUM_ENTRY(ModifierOptions
, Const
), ENUM_ENTRY(ModifierOptions
, Volatile
),
108 ENUM_ENTRY(ModifierOptions
, Unaligned
),
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
),
138 static const EnumEntry
<uint8_t> FunctionOptionEnum
[] = {
139 ENUM_ENTRY(FunctionOptions
, CxxReturnUdt
),
140 ENUM_ENTRY(FunctionOptions
, Constructor
),
141 ENUM_ENTRY(FunctionOptions
, ConstructorWithVirtualBases
),
144 static const EnumEntry
<uint16_t> LabelTypeEnum
[] = {
145 ENUM_ENTRY(LabelType
, Near
), ENUM_ENTRY(LabelType
, Far
),
150 static StringRef
getLeafTypeName(TypeLeafKind LT
) {
152 #define TYPE_RECORD(ename, value, name) \
155 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
159 return "UnknownLeaf";
162 void TypeDumpVisitor::printTypeIndex(StringRef FieldName
, TypeIndex TI
) const {
163 codeview::printTypeIndex(*W
, FieldName
, TI
, TpiTypes
);
166 void TypeDumpVisitor::printItemIndex(StringRef FieldName
, TypeIndex TI
) const {
167 codeview::printTypeIndex(*W
, FieldName
, TI
, getSourceTypes());
170 Error
TypeDumpVisitor::visitTypeBegin(CVType
&Record
) {
171 return visitTypeBegin(Record
, TypeIndex::fromArrayIndex(TpiTypes
.size()));
174 Error
TypeDumpVisitor::visitTypeBegin(CVType
&Record
, TypeIndex Index
) {
175 W
->startLine() << getLeafTypeName(Record
.Type
);
176 W
->getOStream() << " (" << HexNumber(Index
.getIndex()) << ")";
177 W
->getOStream() << " {\n";
179 W
->printEnum("TypeLeafKind", unsigned(Record
.Type
),
180 makeArrayRef(LeafTypeNames
));
181 return Error::success();
184 Error
TypeDumpVisitor::visitTypeEnd(CVType
&Record
) {
185 if (PrintRecordBytes
)
186 W
->printBinaryBlock("LeafData", getBytesAsCharacters(Record
.content()));
189 W
->startLine() << "}\n";
190 return Error::success();
193 Error
TypeDumpVisitor::visitMemberBegin(CVMemberRecord
&Record
) {
194 W
->startLine() << getLeafTypeName(Record
.Kind
);
195 W
->getOStream() << " {\n";
197 W
->printEnum("TypeLeafKind", unsigned(Record
.Kind
),
198 makeArrayRef(LeafTypeNames
));
199 return Error::success();
202 Error
TypeDumpVisitor::visitMemberEnd(CVMemberRecord
&Record
) {
203 if (PrintRecordBytes
)
204 W
->printBinaryBlock("LeafData", getBytesAsCharacters(Record
.Data
));
207 W
->startLine() << "}\n";
208 return Error::success();
211 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
212 FieldListRecord
&FieldList
) {
213 if (auto EC
= codeview::visitMemberRecordStream(FieldList
.Data
, *this))
216 return Error::success();
219 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, StringIdRecord
&String
) {
220 printItemIndex("Id", String
.getId());
221 W
->printString("StringData", String
.getString());
222 return Error::success();
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
]);
233 return Error::success();
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
]);
244 return Error::success();
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();
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();
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();
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();
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();
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();
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();
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();
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());
345 return Error::success();
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();
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();
362 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, PointerRecord
&Ptr
) {
363 printTypeIndex("PointeeType", Ptr
.getReferentType());
364 W
->printHex("PointerAttributes", uint32_t(Ptr
.getOptions()));
365 W
->printEnum("PtrType", unsigned(Ptr
.getPointerKind()),
366 makeArrayRef(PtrKindNames
));
367 W
->printEnum("PtrMode", unsigned(Ptr
.getMode()), makeArrayRef(PtrModeNames
));
369 W
->printNumber("IsFlat", Ptr
.isFlat());
370 W
->printNumber("IsConst", Ptr
.isConst());
371 W
->printNumber("IsVolatile", Ptr
.isVolatile());
372 W
->printNumber("IsUnaligned", Ptr
.isUnaligned());
373 W
->printNumber("IsRestrict", Ptr
.isRestrict());
374 W
->printNumber("SizeOf", Ptr
.getSize());
376 if (Ptr
.isPointerToMember()) {
377 const MemberPointerInfo
&MI
= Ptr
.getMemberInfo();
379 printTypeIndex("ClassType", MI
.getContainingType());
380 W
->printEnum("Representation", uint16_t(MI
.getRepresentation()),
381 makeArrayRef(PtrMemberRepNames
));
384 return Error::success();
387 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, ModifierRecord
&Mod
) {
388 uint16_t Mods
= static_cast<uint16_t>(Mod
.getModifiers());
389 printTypeIndex("ModifiedType", Mod
.getModifiedType());
390 W
->printFlags("Modifiers", Mods
, makeArrayRef(TypeModifierNames
));
392 return Error::success();
395 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, BitFieldRecord
&BitField
) {
396 printTypeIndex("Type", BitField
.getType());
397 W
->printNumber("BitSize", BitField
.getBitSize());
398 W
->printNumber("BitOffset", BitField
.getBitOffset());
399 return Error::success();
402 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
403 VFTableShapeRecord
&Shape
) {
404 W
->printNumber("VFEntryCount", Shape
.getEntryCount());
405 return Error::success();
408 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
409 UdtSourceLineRecord
&Line
) {
410 printTypeIndex("UDT", Line
.getUDT());
411 printItemIndex("SourceFile", Line
.getSourceFile());
412 W
->printNumber("LineNumber", Line
.getLineNumber());
413 return Error::success();
416 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
417 UdtModSourceLineRecord
&Line
) {
418 printTypeIndex("UDT", Line
.getUDT());
419 printItemIndex("SourceFile", Line
.getSourceFile());
420 W
->printNumber("LineNumber", Line
.getLineNumber());
421 W
->printNumber("Module", Line
.getModule());
422 return Error::success();
425 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, BuildInfoRecord
&Args
) {
426 W
->printNumber("NumArgs", static_cast<uint32_t>(Args
.getArgs().size()));
428 ListScope
Arguments(*W
, "Arguments");
429 for (auto Arg
: Args
.getArgs()) {
430 printItemIndex("ArgType", Arg
);
432 return Error::success();
435 void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs
) {
436 return printMemberAttributes(Attrs
.getAccess(), Attrs
.getMethodKind(),
440 void TypeDumpVisitor::printMemberAttributes(MemberAccess Access
,
442 MethodOptions Options
) {
443 W
->printEnum("AccessSpecifier", uint8_t(Access
),
444 makeArrayRef(MemberAccessNames
));
445 // Data members will be vanilla. Don't try to print a method kind for them.
446 if (Kind
!= MethodKind::Vanilla
)
447 W
->printEnum("MethodKind", unsigned(Kind
), makeArrayRef(MemberKindNames
));
448 if (Options
!= MethodOptions::None
) {
449 W
->printFlags("MethodOptions", unsigned(Options
),
450 makeArrayRef(MethodOptionNames
));
454 Error
TypeDumpVisitor::visitUnknownMember(CVMemberRecord
&Record
) {
455 W
->printHex("UnknownMember", unsigned(Record
.Kind
));
456 return Error::success();
459 Error
TypeDumpVisitor::visitUnknownType(CVType
&Record
) {
460 W
->printEnum("Kind", uint16_t(Record
.kind()), makeArrayRef(LeafTypeNames
));
461 W
->printNumber("Length", uint32_t(Record
.content().size()));
462 return Error::success();
465 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
466 NestedTypeRecord
&Nested
) {
467 printTypeIndex("Type", Nested
.getNestedType());
468 W
->printString("Name", Nested
.getName());
469 return Error::success();
472 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
473 OneMethodRecord
&Method
) {
474 MethodKind K
= Method
.getMethodKind();
475 printMemberAttributes(Method
.getAccess(), K
, Method
.getOptions());
476 printTypeIndex("Type", Method
.getType());
477 // If virtual, then read the vftable offset.
478 if (Method
.isIntroducingVirtual())
479 W
->printHex("VFTableOffset", Method
.getVFTableOffset());
480 W
->printString("Name", Method
.getName());
481 return Error::success();
484 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
485 OverloadedMethodRecord
&Method
) {
486 W
->printHex("MethodCount", Method
.getNumOverloads());
487 printTypeIndex("MethodListIndex", Method
.getMethodList());
488 W
->printString("Name", Method
.getName());
489 return Error::success();
492 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
493 DataMemberRecord
&Field
) {
494 printMemberAttributes(Field
.getAccess(), MethodKind::Vanilla
,
495 MethodOptions::None
);
496 printTypeIndex("Type", Field
.getType());
497 W
->printHex("FieldOffset", Field
.getFieldOffset());
498 W
->printString("Name", Field
.getName());
499 return Error::success();
502 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
503 StaticDataMemberRecord
&Field
) {
504 printMemberAttributes(Field
.getAccess(), MethodKind::Vanilla
,
505 MethodOptions::None
);
506 printTypeIndex("Type", Field
.getType());
507 W
->printString("Name", Field
.getName());
508 return Error::success();
511 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
512 VFPtrRecord
&VFTable
) {
513 printTypeIndex("Type", VFTable
.getType());
514 return Error::success();
517 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
518 EnumeratorRecord
&Enum
) {
519 printMemberAttributes(Enum
.getAccess(), MethodKind::Vanilla
,
520 MethodOptions::None
);
521 W
->printNumber("EnumValue", Enum
.getValue());
522 W
->printString("Name", Enum
.getName());
523 return Error::success();
526 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
527 BaseClassRecord
&Base
) {
528 printMemberAttributes(Base
.getAccess(), MethodKind::Vanilla
,
529 MethodOptions::None
);
530 printTypeIndex("BaseType", Base
.getBaseType());
531 W
->printHex("BaseOffset", Base
.getBaseOffset());
532 return Error::success();
535 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
536 VirtualBaseClassRecord
&Base
) {
537 printMemberAttributes(Base
.getAccess(), MethodKind::Vanilla
,
538 MethodOptions::None
);
539 printTypeIndex("BaseType", Base
.getBaseType());
540 printTypeIndex("VBPtrType", Base
.getVBPtrType());
541 W
->printHex("VBPtrOffset", Base
.getVBPtrOffset());
542 W
->printHex("VBTableIndex", Base
.getVTableIndex());
543 return Error::success();
546 Error
TypeDumpVisitor::visitKnownMember(CVMemberRecord
&CVR
,
547 ListContinuationRecord
&Cont
) {
548 printTypeIndex("ContinuationIndex", Cont
.getContinuationIndex());
549 return Error::success();
552 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, LabelRecord
&LR
) {
553 W
->printEnum("Mode", uint16_t(LR
.Mode
), makeArrayRef(LabelTypeEnum
));
554 return Error::success();
557 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
558 PrecompRecord
&Precomp
) {
559 W
->printHex("StartIndex", Precomp
.getStartTypeIndex());
560 W
->printHex("Count", Precomp
.getTypesCount());
561 W
->printHex("Signature", Precomp
.getSignature());
562 W
->printString("PrecompFile", Precomp
.getPrecompFilePath());
563 return Error::success();
566 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
567 EndPrecompRecord
&EndPrecomp
) {
568 W
->printHex("Signature", EndPrecomp
.getSignature());
569 return Error::success();