1 //===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
13 #include "llvm/DebugInfo/CodeView/Formatters.h"
14 #include "llvm/DebugInfo/CodeView/TypeCollection.h"
15 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
16 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
17 #include "llvm/Support/FormatVariadic.h"
18 #include "llvm/Support/ScopedPrinter.h"
21 using namespace llvm::codeview
;
23 static const EnumEntry
<TypeLeafKind
> LeafTypeNames
[] = {
24 #define CV_TYPE(enum, val) {#enum, enum},
25 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
28 #define ENUM_ENTRY(enum_class, enum) \
29 { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
31 static const EnumEntry
<uint16_t> ClassOptionNames
[] = {
32 ENUM_ENTRY(ClassOptions
, Packed
),
33 ENUM_ENTRY(ClassOptions
, HasConstructorOrDestructor
),
34 ENUM_ENTRY(ClassOptions
, HasOverloadedOperator
),
35 ENUM_ENTRY(ClassOptions
, Nested
),
36 ENUM_ENTRY(ClassOptions
, ContainsNestedClass
),
37 ENUM_ENTRY(ClassOptions
, HasOverloadedAssignmentOperator
),
38 ENUM_ENTRY(ClassOptions
, HasConversionOperator
),
39 ENUM_ENTRY(ClassOptions
, ForwardReference
),
40 ENUM_ENTRY(ClassOptions
, Scoped
),
41 ENUM_ENTRY(ClassOptions
, HasUniqueName
),
42 ENUM_ENTRY(ClassOptions
, Sealed
),
43 ENUM_ENTRY(ClassOptions
, Intrinsic
),
46 static const EnumEntry
<uint8_t> MemberAccessNames
[] = {
47 ENUM_ENTRY(MemberAccess
, None
), ENUM_ENTRY(MemberAccess
, Private
),
48 ENUM_ENTRY(MemberAccess
, Protected
), ENUM_ENTRY(MemberAccess
, Public
),
51 static const EnumEntry
<uint16_t> MethodOptionNames
[] = {
52 ENUM_ENTRY(MethodOptions
, Pseudo
),
53 ENUM_ENTRY(MethodOptions
, NoInherit
),
54 ENUM_ENTRY(MethodOptions
, NoConstruct
),
55 ENUM_ENTRY(MethodOptions
, CompilerGenerated
),
56 ENUM_ENTRY(MethodOptions
, Sealed
),
59 static const EnumEntry
<uint16_t> MemberKindNames
[] = {
60 ENUM_ENTRY(MethodKind
, Vanilla
),
61 ENUM_ENTRY(MethodKind
, Virtual
),
62 ENUM_ENTRY(MethodKind
, Static
),
63 ENUM_ENTRY(MethodKind
, Friend
),
64 ENUM_ENTRY(MethodKind
, IntroducingVirtual
),
65 ENUM_ENTRY(MethodKind
, PureVirtual
),
66 ENUM_ENTRY(MethodKind
, PureIntroducingVirtual
),
69 static const EnumEntry
<uint8_t> PtrKindNames
[] = {
70 ENUM_ENTRY(PointerKind
, Near16
),
71 ENUM_ENTRY(PointerKind
, Far16
),
72 ENUM_ENTRY(PointerKind
, Huge16
),
73 ENUM_ENTRY(PointerKind
, BasedOnSegment
),
74 ENUM_ENTRY(PointerKind
, BasedOnValue
),
75 ENUM_ENTRY(PointerKind
, BasedOnSegmentValue
),
76 ENUM_ENTRY(PointerKind
, BasedOnAddress
),
77 ENUM_ENTRY(PointerKind
, BasedOnSegmentAddress
),
78 ENUM_ENTRY(PointerKind
, BasedOnType
),
79 ENUM_ENTRY(PointerKind
, BasedOnSelf
),
80 ENUM_ENTRY(PointerKind
, Near32
),
81 ENUM_ENTRY(PointerKind
, Far32
),
82 ENUM_ENTRY(PointerKind
, Near64
),
85 static const EnumEntry
<uint8_t> PtrModeNames
[] = {
86 ENUM_ENTRY(PointerMode
, Pointer
),
87 ENUM_ENTRY(PointerMode
, LValueReference
),
88 ENUM_ENTRY(PointerMode
, PointerToDataMember
),
89 ENUM_ENTRY(PointerMode
, PointerToMemberFunction
),
90 ENUM_ENTRY(PointerMode
, RValueReference
),
93 static const EnumEntry
<uint16_t> PtrMemberRepNames
[] = {
94 ENUM_ENTRY(PointerToMemberRepresentation
, Unknown
),
95 ENUM_ENTRY(PointerToMemberRepresentation
, SingleInheritanceData
),
96 ENUM_ENTRY(PointerToMemberRepresentation
, MultipleInheritanceData
),
97 ENUM_ENTRY(PointerToMemberRepresentation
, VirtualInheritanceData
),
98 ENUM_ENTRY(PointerToMemberRepresentation
, GeneralData
),
99 ENUM_ENTRY(PointerToMemberRepresentation
, SingleInheritanceFunction
),
100 ENUM_ENTRY(PointerToMemberRepresentation
, MultipleInheritanceFunction
),
101 ENUM_ENTRY(PointerToMemberRepresentation
, VirtualInheritanceFunction
),
102 ENUM_ENTRY(PointerToMemberRepresentation
, GeneralFunction
),
105 static const EnumEntry
<uint16_t> TypeModifierNames
[] = {
106 ENUM_ENTRY(ModifierOptions
, Const
), ENUM_ENTRY(ModifierOptions
, Volatile
),
107 ENUM_ENTRY(ModifierOptions
, Unaligned
),
110 static const EnumEntry
<uint8_t> CallingConventions
[] = {
111 ENUM_ENTRY(CallingConvention
, NearC
),
112 ENUM_ENTRY(CallingConvention
, FarC
),
113 ENUM_ENTRY(CallingConvention
, NearPascal
),
114 ENUM_ENTRY(CallingConvention
, FarPascal
),
115 ENUM_ENTRY(CallingConvention
, NearFast
),
116 ENUM_ENTRY(CallingConvention
, FarFast
),
117 ENUM_ENTRY(CallingConvention
, NearStdCall
),
118 ENUM_ENTRY(CallingConvention
, FarStdCall
),
119 ENUM_ENTRY(CallingConvention
, NearSysCall
),
120 ENUM_ENTRY(CallingConvention
, FarSysCall
),
121 ENUM_ENTRY(CallingConvention
, ThisCall
),
122 ENUM_ENTRY(CallingConvention
, MipsCall
),
123 ENUM_ENTRY(CallingConvention
, Generic
),
124 ENUM_ENTRY(CallingConvention
, AlphaCall
),
125 ENUM_ENTRY(CallingConvention
, PpcCall
),
126 ENUM_ENTRY(CallingConvention
, SHCall
),
127 ENUM_ENTRY(CallingConvention
, ArmCall
),
128 ENUM_ENTRY(CallingConvention
, AM33Call
),
129 ENUM_ENTRY(CallingConvention
, TriCall
),
130 ENUM_ENTRY(CallingConvention
, SH5Call
),
131 ENUM_ENTRY(CallingConvention
, M32RCall
),
132 ENUM_ENTRY(CallingConvention
, ClrCall
),
133 ENUM_ENTRY(CallingConvention
, Inline
),
134 ENUM_ENTRY(CallingConvention
, NearVector
),
137 static const EnumEntry
<uint8_t> FunctionOptionEnum
[] = {
138 ENUM_ENTRY(FunctionOptions
, CxxReturnUdt
),
139 ENUM_ENTRY(FunctionOptions
, Constructor
),
140 ENUM_ENTRY(FunctionOptions
, ConstructorWithVirtualBases
),
143 static const EnumEntry
<uint16_t> LabelTypeEnum
[] = {
144 ENUM_ENTRY(LabelType
, Near
), ENUM_ENTRY(LabelType
, Far
),
149 static StringRef
getLeafTypeName(TypeLeafKind LT
) {
151 #define TYPE_RECORD(ename, value, name) \
154 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
158 return "UnknownLeaf";
161 void TypeDumpVisitor::printTypeIndex(StringRef FieldName
, TypeIndex TI
) const {
162 codeview::printTypeIndex(*W
, FieldName
, TI
, TpiTypes
);
165 void TypeDumpVisitor::printItemIndex(StringRef FieldName
, TypeIndex TI
) const {
166 codeview::printTypeIndex(*W
, FieldName
, TI
, getSourceTypes());
169 Error
TypeDumpVisitor::visitTypeBegin(CVType
&Record
) {
170 return visitTypeBegin(Record
, TypeIndex::fromArrayIndex(TpiTypes
.size()));
173 Error
TypeDumpVisitor::visitTypeBegin(CVType
&Record
, TypeIndex Index
) {
174 W
->startLine() << getLeafTypeName(Record
.kind());
175 W
->getOStream() << " (" << HexNumber(Index
.getIndex()) << ")";
176 W
->getOStream() << " {\n";
178 W
->printEnum("TypeLeafKind", unsigned(Record
.kind()),
179 makeArrayRef(LeafTypeNames
));
180 return Error::success();
183 Error
TypeDumpVisitor::visitTypeEnd(CVType
&Record
) {
184 if (PrintRecordBytes
)
185 W
->printBinaryBlock("LeafData", getBytesAsCharacters(Record
.content()));
188 W
->startLine() << "}\n";
189 return Error::success();
192 Error
TypeDumpVisitor::visitMemberBegin(CVMemberRecord
&Record
) {
193 W
->startLine() << getLeafTypeName(Record
.Kind
);
194 W
->getOStream() << " {\n";
196 W
->printEnum("TypeLeafKind", unsigned(Record
.Kind
),
197 makeArrayRef(LeafTypeNames
));
198 return Error::success();
201 Error
TypeDumpVisitor::visitMemberEnd(CVMemberRecord
&Record
) {
202 if (PrintRecordBytes
)
203 W
->printBinaryBlock("LeafData", getBytesAsCharacters(Record
.Data
));
206 W
->startLine() << "}\n";
207 return Error::success();
210 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
211 FieldListRecord
&FieldList
) {
212 if (auto EC
= codeview::visitMemberRecordStream(FieldList
.Data
, *this))
215 return Error::success();
218 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, StringIdRecord
&String
) {
219 printItemIndex("Id", String
.getId());
220 W
->printString("StringData", String
.getString());
221 return Error::success();
224 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, ArgListRecord
&Args
) {
225 auto Indices
= Args
.getIndices();
226 uint32_t Size
= Indices
.size();
227 W
->printNumber("NumArgs", Size
);
228 ListScope
Arguments(*W
, "Arguments");
229 for (uint32_t I
= 0; I
< Size
; ++I
) {
230 printTypeIndex("ArgType", Indices
[I
]);
232 return Error::success();
235 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, StringListRecord
&Strs
) {
236 auto Indices
= Strs
.getIndices();
237 uint32_t Size
= Indices
.size();
238 W
->printNumber("NumStrings", Size
);
239 ListScope
Arguments(*W
, "Strings");
240 for (uint32_t I
= 0; I
< Size
; ++I
) {
241 printItemIndex("String", Indices
[I
]);
243 return Error::success();
246 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, ClassRecord
&Class
) {
247 uint16_t Props
= static_cast<uint16_t>(Class
.getOptions());
248 W
->printNumber("MemberCount", Class
.getMemberCount());
249 W
->printFlags("Properties", Props
, makeArrayRef(ClassOptionNames
));
250 printTypeIndex("FieldList", Class
.getFieldList());
251 printTypeIndex("DerivedFrom", Class
.getDerivationList());
252 printTypeIndex("VShape", Class
.getVTableShape());
253 W
->printNumber("SizeOf", Class
.getSize());
254 W
->printString("Name", Class
.getName());
255 if (Props
& uint16_t(ClassOptions::HasUniqueName
))
256 W
->printString("LinkageName", Class
.getUniqueName());
257 return Error::success();
260 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, UnionRecord
&Union
) {
261 uint16_t Props
= static_cast<uint16_t>(Union
.getOptions());
262 W
->printNumber("MemberCount", Union
.getMemberCount());
263 W
->printFlags("Properties", Props
, makeArrayRef(ClassOptionNames
));
264 printTypeIndex("FieldList", Union
.getFieldList());
265 W
->printNumber("SizeOf", Union
.getSize());
266 W
->printString("Name", Union
.getName());
267 if (Props
& uint16_t(ClassOptions::HasUniqueName
))
268 W
->printString("LinkageName", Union
.getUniqueName());
269 return Error::success();
272 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, EnumRecord
&Enum
) {
273 uint16_t Props
= static_cast<uint16_t>(Enum
.getOptions());
274 W
->printNumber("NumEnumerators", Enum
.getMemberCount());
275 W
->printFlags("Properties", uint16_t(Enum
.getOptions()),
276 makeArrayRef(ClassOptionNames
));
277 printTypeIndex("UnderlyingType", Enum
.getUnderlyingType());
278 printTypeIndex("FieldListType", Enum
.getFieldList());
279 W
->printString("Name", Enum
.getName());
280 if (Props
& uint16_t(ClassOptions::HasUniqueName
))
281 W
->printString("LinkageName", Enum
.getUniqueName());
282 return Error::success();
285 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, ArrayRecord
&AT
) {
286 printTypeIndex("ElementType", AT
.getElementType());
287 printTypeIndex("IndexType", AT
.getIndexType());
288 W
->printNumber("SizeOf", AT
.getSize());
289 W
->printString("Name", AT
.getName());
290 return Error::success();
293 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, VFTableRecord
&VFT
) {
294 printTypeIndex("CompleteClass", VFT
.getCompleteClass());
295 printTypeIndex("OverriddenVFTable", VFT
.getOverriddenVTable());
296 W
->printHex("VFPtrOffset", VFT
.getVFPtrOffset());
297 W
->printString("VFTableName", VFT
.getName());
298 for (auto N
: VFT
.getMethodNames())
299 W
->printString("MethodName", N
);
300 return Error::success();
303 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, MemberFuncIdRecord
&Id
) {
304 printTypeIndex("ClassType", Id
.getClassType());
305 printTypeIndex("FunctionType", Id
.getFunctionType());
306 W
->printString("Name", Id
.getName());
307 return Error::success();
310 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, ProcedureRecord
&Proc
) {
311 printTypeIndex("ReturnType", Proc
.getReturnType());
312 W
->printEnum("CallingConvention", uint8_t(Proc
.getCallConv()),
313 makeArrayRef(CallingConventions
));
314 W
->printFlags("FunctionOptions", uint8_t(Proc
.getOptions()),
315 makeArrayRef(FunctionOptionEnum
));
316 W
->printNumber("NumParameters", Proc
.getParameterCount());
317 printTypeIndex("ArgListType", Proc
.getArgumentList());
318 return Error::success();
321 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, MemberFunctionRecord
&MF
) {
322 printTypeIndex("ReturnType", MF
.getReturnType());
323 printTypeIndex("ClassType", MF
.getClassType());
324 printTypeIndex("ThisType", MF
.getThisType());
325 W
->printEnum("CallingConvention", uint8_t(MF
.getCallConv()),
326 makeArrayRef(CallingConventions
));
327 W
->printFlags("FunctionOptions", uint8_t(MF
.getOptions()),
328 makeArrayRef(FunctionOptionEnum
));
329 W
->printNumber("NumParameters", MF
.getParameterCount());
330 printTypeIndex("ArgListType", MF
.getArgumentList());
331 W
->printNumber("ThisAdjustment", MF
.getThisPointerAdjustment());
332 return Error::success();
335 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
,
336 MethodOverloadListRecord
&MethodList
) {
337 for (auto &M
: MethodList
.getMethods()) {
338 ListScope
S(*W
, "Method");
339 printMemberAttributes(M
.getAccess(), M
.getMethodKind(), M
.getOptions());
340 printTypeIndex("Type", M
.getType());
341 if (M
.isIntroducingVirtual())
342 W
->printHex("VFTableOffset", M
.getVFTableOffset());
344 return Error::success();
347 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, FuncIdRecord
&Func
) {
348 printItemIndex("ParentScope", Func
.getParentScope());
349 printTypeIndex("FunctionType", Func
.getFunctionType());
350 W
->printString("Name", Func
.getName());
351 return Error::success();
354 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, TypeServer2Record
&TS
) {
355 W
->printString("Guid", formatv("{0}", TS
.getGuid()).str());
356 W
->printNumber("Age", TS
.getAge());
357 W
->printString("Name", TS
.getName());
358 return Error::success();
361 Error
TypeDumpVisitor::visitKnownRecord(CVType
&CVR
, PointerRecord
&Ptr
) {
362 printTypeIndex("PointeeType", Ptr
.getReferentType());
363 W
->printEnum("PtrType", unsigned(Ptr
.getPointerKind()),
364 makeArrayRef(PtrKindNames
));
365 W
->printEnum("PtrMode", unsigned(Ptr
.getMode()), makeArrayRef(PtrModeNames
));
367 W
->printNumber("IsFlat", Ptr
.isFlat());
368 W
->printNumber("IsConst", Ptr
.isConst());
369 W
->printNumber("IsVolatile", Ptr
.isVolatile());
370 W
->printNumber("IsUnaligned", Ptr
.isUnaligned());
371 W
->printNumber("IsRestrict", Ptr
.isRestrict());
372 W
->printNumber("IsThisPtr&", Ptr
.isLValueReferenceThisPtr());
373 W
->printNumber("IsThisPtr&&", Ptr
.isRValueReferenceThisPtr());
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();