1//===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
10
11#include "llvm/ADT/ArrayRef.h"
12#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
13#include "llvm/DebugInfo/CodeView/RecordSerialization.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"
19#include "llvm/Support/raw_ostream.h"
20
21using namespace llvm;
22using namespace llvm::codeview;
23
24static 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_t<enum_class>(enum_class::enum) }
31
32static 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
47static 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
52static 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
60static 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
70static 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
86static 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
94static 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
106static const EnumEntry<uint16_t> TypeModifierNames[] = {
107 ENUM_ENTRY(ModifierOptions, Const), ENUM_ENTRY(ModifierOptions, Volatile),
108 ENUM_ENTRY(ModifierOptions, Unaligned),
109};
110
111static 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 ENUM_ENTRY(CallingConvention, Swift),
137};
138
139static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
140 ENUM_ENTRY(FunctionOptions, CxxReturnUdt),
141 ENUM_ENTRY(FunctionOptions, Constructor),
142 ENUM_ENTRY(FunctionOptions, ConstructorWithVirtualBases),
143};
144
145static const EnumEntry<uint16_t> LabelTypeEnum[] = {
146 ENUM_ENTRY(LabelType, Near), ENUM_ENTRY(LabelType, Far),
147};
148
149#undef ENUM_ENTRY
150
151static StringRef getLeafTypeName(TypeLeafKind LT) {
152 switch (LT) {
153#define TYPE_RECORD(ename, value, name) \
154 case ename: \
155 return #name;
156#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
157 default:
158 break;
159 }
160 return "UnknownLeaf";
161}
162
163void TypeDumpVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
164 codeview::printTypeIndex(Printer&: *W, FieldName, TI, Types&: TpiTypes);
165}
166
167void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
168 codeview::printTypeIndex(Printer&: *W, FieldName, TI, Types&: getSourceTypes());
169}
170
171Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
172 return visitTypeBegin(Record, Index: TypeIndex::fromArrayIndex(Index: TpiTypes.size()));
173}
174
175Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
176 W->startLine() << getLeafTypeName(LT: Record.kind());
177 W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
178 W->getOStream() << " {\n";
179 W->indent();
180 W->printEnum(Label: "TypeLeafKind", Value: unsigned(Record.kind()),
181 EnumValues: ArrayRef(LeafTypeNames));
182 return Error::success();
183}
184
185Error TypeDumpVisitor::visitTypeEnd(CVType &Record) {
186 if (PrintRecordBytes)
187 W->printBinaryBlock(Label: "LeafData", Value: getBytesAsCharacters(LeafData: Record.content()));
188
189 W->unindent();
190 W->startLine() << "}\n";
191 return Error::success();
192}
193
194Error TypeDumpVisitor::visitMemberBegin(CVMemberRecord &Record) {
195 W->startLine() << getLeafTypeName(LT: Record.Kind);
196 W->getOStream() << " {\n";
197 W->indent();
198 W->printEnum(Label: "TypeLeafKind", Value: unsigned(Record.Kind), EnumValues: ArrayRef(LeafTypeNames));
199 return Error::success();
200}
201
202Error TypeDumpVisitor::visitMemberEnd(CVMemberRecord &Record) {
203 if (PrintRecordBytes)
204 W->printBinaryBlock(Label: "LeafData", Value: getBytesAsCharacters(LeafData: Record.Data));
205
206 W->unindent();
207 W->startLine() << "}\n";
208 return Error::success();
209}
210
211Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
212 FieldListRecord &FieldList) {
213 if (auto EC = codeview::visitMemberRecordStream(FieldList: FieldList.Data, Callbacks&: *this))
214 return EC;
215
216 return Error::success();
217}
218
219Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringIdRecord &String) {
220 printItemIndex(FieldName: "Id", TI: String.getId());
221 W->printString(Label: "StringData", Value: String.getString());
222 return Error::success();
223}
224
225Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
226 auto Indices = Args.getIndices();
227 uint32_t Size = Indices.size();
228 W->printNumber(Label: "NumArgs", Value: Size);
229 ListScope Arguments(*W, "Arguments");
230 for (uint32_t I = 0; I < Size; ++I) {
231 printTypeIndex(FieldName: "ArgType", TI: Indices[I]);
232 }
233 return Error::success();
234}
235
236Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringListRecord &Strs) {
237 auto Indices = Strs.getIndices();
238 uint32_t Size = Indices.size();
239 W->printNumber(Label: "NumStrings", Value: Size);
240 ListScope Arguments(*W, "Strings");
241 for (uint32_t I = 0; I < Size; ++I) {
242 printItemIndex(FieldName: "String", TI: Indices[I]);
243 }
244 return Error::success();
245}
246
247Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
248 uint16_t Props = static_cast<uint16_t>(Class.getOptions());
249 W->printNumber(Label: "MemberCount", Value: Class.getMemberCount());
250 W->printFlags(Label: "Properties", Value: Props, Flags: ArrayRef(ClassOptionNames));
251 printTypeIndex(FieldName: "FieldList", TI: Class.getFieldList());
252 printTypeIndex(FieldName: "DerivedFrom", TI: Class.getDerivationList());
253 printTypeIndex(FieldName: "VShape", TI: Class.getVTableShape());
254 W->printNumber(Label: "SizeOf", Value: Class.getSize());
255 W->printString(Label: "Name", Value: Class.getName());
256 if (Props & uint16_t(ClassOptions::HasUniqueName))
257 W->printString(Label: "LinkageName", Value: Class.getUniqueName());
258 return Error::success();
259}
260
261Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
262 uint16_t Props = static_cast<uint16_t>(Union.getOptions());
263 W->printNumber(Label: "MemberCount", Value: Union.getMemberCount());
264 W->printFlags(Label: "Properties", Value: Props, Flags: ArrayRef(ClassOptionNames));
265 printTypeIndex(FieldName: "FieldList", TI: Union.getFieldList());
266 W->printNumber(Label: "SizeOf", Value: Union.getSize());
267 W->printString(Label: "Name", Value: Union.getName());
268 if (Props & uint16_t(ClassOptions::HasUniqueName))
269 W->printString(Label: "LinkageName", Value: Union.getUniqueName());
270 return Error::success();
271}
272
273Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
274 uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
275 W->printNumber(Label: "NumEnumerators", Value: Enum.getMemberCount());
276 W->printFlags(Label: "Properties", Value: uint16_t(Enum.getOptions()),
277 Flags: ArrayRef(ClassOptionNames));
278 printTypeIndex(FieldName: "UnderlyingType", TI: Enum.getUnderlyingType());
279 printTypeIndex(FieldName: "FieldListType", TI: Enum.getFieldList());
280 W->printString(Label: "Name", Value: Enum.getName());
281 if (Props & uint16_t(ClassOptions::HasUniqueName))
282 W->printString(Label: "LinkageName", Value: Enum.getUniqueName());
283 return Error::success();
284}
285
286Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
287 printTypeIndex(FieldName: "ElementType", TI: AT.getElementType());
288 printTypeIndex(FieldName: "IndexType", TI: AT.getIndexType());
289 W->printNumber(Label: "SizeOf", Value: AT.getSize());
290 W->printString(Label: "Name", Value: AT.getName());
291 return Error::success();
292}
293
294Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
295 printTypeIndex(FieldName: "CompleteClass", TI: VFT.getCompleteClass());
296 printTypeIndex(FieldName: "OverriddenVFTable", TI: VFT.getOverriddenVTable());
297 W->printHex(Label: "VFPtrOffset", Value: VFT.getVFPtrOffset());
298 W->printString(Label: "VFTableName", Value: VFT.getName());
299 for (auto N : VFT.getMethodNames())
300 W->printString(Label: "MethodName", Value: N);
301 return Error::success();
302}
303
304Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
305 printTypeIndex(FieldName: "ClassType", TI: Id.getClassType());
306 printTypeIndex(FieldName: "FunctionType", TI: Id.getFunctionType());
307 W->printString(Label: "Name", Value: Id.getName());
308 return Error::success();
309}
310
311Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
312 printTypeIndex(FieldName: "ReturnType", TI: Proc.getReturnType());
313 W->printEnum(Label: "CallingConvention", Value: uint8_t(Proc.getCallConv()),
314 EnumValues: ArrayRef(CallingConventions));
315 W->printFlags(Label: "FunctionOptions", Value: uint8_t(Proc.getOptions()),
316 Flags: ArrayRef(FunctionOptionEnum));
317 W->printNumber(Label: "NumParameters", Value: Proc.getParameterCount());
318 printTypeIndex(FieldName: "ArgListType", TI: Proc.getArgumentList());
319 return Error::success();
320}
321
322Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFunctionRecord &MF) {
323 printTypeIndex(FieldName: "ReturnType", TI: MF.getReturnType());
324 printTypeIndex(FieldName: "ClassType", TI: MF.getClassType());
325 printTypeIndex(FieldName: "ThisType", TI: MF.getThisType());
326 W->printEnum(Label: "CallingConvention", Value: uint8_t(MF.getCallConv()),
327 EnumValues: ArrayRef(CallingConventions));
328 W->printFlags(Label: "FunctionOptions", Value: uint8_t(MF.getOptions()),
329 Flags: ArrayRef(FunctionOptionEnum));
330 W->printNumber(Label: "NumParameters", Value: MF.getParameterCount());
331 printTypeIndex(FieldName: "ArgListType", TI: MF.getArgumentList());
332 W->printNumber(Label: "ThisAdjustment", Value: MF.getThisPointerAdjustment());
333 return Error::success();
334}
335
336Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
337 MethodOverloadListRecord &MethodList) {
338 for (const auto &M : MethodList.getMethods()) {
339 ListScope S(*W, "Method");
340 printMemberAttributes(Access: M.getAccess(), Kind: M.getMethodKind(), Options: M.getOptions());
341 printTypeIndex(FieldName: "Type", TI: M.getType());
342 if (M.isIntroducingVirtual())
343 W->printHex(Label: "VFTableOffset", Value: M.getVFTableOffset());
344 }
345 return Error::success();
346}
347
348Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
349 printItemIndex(FieldName: "ParentScope", TI: Func.getParentScope());
350 printTypeIndex(FieldName: "FunctionType", TI: Func.getFunctionType());
351 W->printString(Label: "Name", Value: Func.getName());
352 return Error::success();
353}
354
355Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
356 W->printString(Label: "Guid", Value: formatv(Fmt: "{0}", Vals: TS.getGuid()).str());
357 W->printNumber(Label: "Age", Value: TS.getAge());
358 W->printString(Label: "Name", Value: TS.getName());
359 return Error::success();
360}
361
362Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
363 printTypeIndex(FieldName: "PointeeType", TI: Ptr.getReferentType());
364 W->printEnum(Label: "PtrType", Value: unsigned(Ptr.getPointerKind()),
365 EnumValues: ArrayRef(PtrKindNames));
366 W->printEnum(Label: "PtrMode", Value: unsigned(Ptr.getMode()), EnumValues: ArrayRef(PtrModeNames));
367
368 W->printNumber(Label: "IsFlat", Value: Ptr.isFlat());
369 W->printNumber(Label: "IsConst", Value: Ptr.isConst());
370 W->printNumber(Label: "IsVolatile", Value: Ptr.isVolatile());
371 W->printNumber(Label: "IsUnaligned", Value: Ptr.isUnaligned());
372 W->printNumber(Label: "IsRestrict", Value: Ptr.isRestrict());
373 W->printNumber(Label: "IsThisPtr&", Value: Ptr.isLValueReferenceThisPtr());
374 W->printNumber(Label: "IsThisPtr&&", Value: Ptr.isRValueReferenceThisPtr());
375 W->printNumber(Label: "SizeOf", Value: Ptr.getSize());
376
377 if (Ptr.isPointerToMember()) {
378 const MemberPointerInfo &MI = Ptr.getMemberInfo();
379
380 printTypeIndex(FieldName: "ClassType", TI: MI.getContainingType());
381 W->printEnum(Label: "Representation", Value: uint16_t(MI.getRepresentation()),
382 EnumValues: ArrayRef(PtrMemberRepNames));
383 }
384
385 return Error::success();
386}
387
388Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
389 uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
390 printTypeIndex(FieldName: "ModifiedType", TI: Mod.getModifiedType());
391 W->printFlags(Label: "Modifiers", Value: Mods, Flags: ArrayRef(TypeModifierNames));
392
393 return Error::success();
394}
395
396Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BitFieldRecord &BitField) {
397 printTypeIndex(FieldName: "Type", TI: BitField.getType());
398 W->printNumber(Label: "BitSize", Value: BitField.getBitSize());
399 W->printNumber(Label: "BitOffset", Value: BitField.getBitOffset());
400 return Error::success();
401}
402
403Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
404 VFTableShapeRecord &Shape) {
405 W->printNumber(Label: "VFEntryCount", Value: Shape.getEntryCount());
406 return Error::success();
407}
408
409Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
410 UdtSourceLineRecord &Line) {
411 printTypeIndex(FieldName: "UDT", TI: Line.getUDT());
412 printItemIndex(FieldName: "SourceFile", TI: Line.getSourceFile());
413 W->printNumber(Label: "LineNumber", Value: Line.getLineNumber());
414 return Error::success();
415}
416
417Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
418 UdtModSourceLineRecord &Line) {
419 printTypeIndex(FieldName: "UDT", TI: Line.getUDT());
420 printItemIndex(FieldName: "SourceFile", TI: Line.getSourceFile());
421 W->printNumber(Label: "LineNumber", Value: Line.getLineNumber());
422 W->printNumber(Label: "Module", Value: Line.getModule());
423 return Error::success();
424}
425
426Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &Args) {
427 W->printNumber(Label: "NumArgs", Value: static_cast<uint32_t>(Args.getArgs().size()));
428
429 ListScope Arguments(*W, "Arguments");
430 for (auto Arg : Args.getArgs()) {
431 printItemIndex(FieldName: "ArgType", TI: Arg);
432 }
433 return Error::success();
434}
435
436void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs) {
437 return printMemberAttributes(Access: Attrs.getAccess(), Kind: Attrs.getMethodKind(),
438 Options: Attrs.getFlags());
439}
440
441void TypeDumpVisitor::printMemberAttributes(MemberAccess Access,
442 MethodKind Kind,
443 MethodOptions Options) {
444 W->printEnum(Label: "AccessSpecifier", Value: uint8_t(Access), EnumValues: ArrayRef(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(Label: "MethodKind", Value: unsigned(Kind), EnumValues: ArrayRef(MemberKindNames));
448 if (Options != MethodOptions::None) {
449 W->printFlags(Label: "MethodOptions", Value: unsigned(Options),
450 Flags: ArrayRef(MethodOptionNames));
451 }
452}
453
454Error TypeDumpVisitor::visitUnknownMember(CVMemberRecord &Record) {
455 W->printHex(Label: "UnknownMember", Value: unsigned(Record.Kind));
456 return Error::success();
457}
458
459Error TypeDumpVisitor::visitUnknownType(CVType &Record) {
460 W->printEnum(Label: "Kind", Value: uint16_t(Record.kind()), EnumValues: ArrayRef(LeafTypeNames));
461 W->printNumber(Label: "Length", Value: uint32_t(Record.content().size()));
462 return Error::success();
463}
464
465Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
466 NestedTypeRecord &Nested) {
467 printTypeIndex(FieldName: "Type", TI: Nested.getNestedType());
468 W->printString(Label: "Name", Value: Nested.getName());
469 return Error::success();
470}
471
472Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
473 OneMethodRecord &Method) {
474 MethodKind K = Method.getMethodKind();
475 printMemberAttributes(Access: Method.getAccess(), Kind: K, Options: Method.getOptions());
476 printTypeIndex(FieldName: "Type", TI: Method.getType());
477 // If virtual, then read the vftable offset.
478 if (Method.isIntroducingVirtual())
479 W->printHex(Label: "VFTableOffset", Value: Method.getVFTableOffset());
480 W->printString(Label: "Name", Value: Method.getName());
481 return Error::success();
482}
483
484Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
485 OverloadedMethodRecord &Method) {
486 W->printHex(Label: "MethodCount", Value: Method.getNumOverloads());
487 printTypeIndex(FieldName: "MethodListIndex", TI: Method.getMethodList());
488 W->printString(Label: "Name", Value: Method.getName());
489 return Error::success();
490}
491
492Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
493 DataMemberRecord &Field) {
494 printMemberAttributes(Access: Field.getAccess(), Kind: MethodKind::Vanilla,
495 Options: MethodOptions::None);
496 printTypeIndex(FieldName: "Type", TI: Field.getType());
497 W->printHex(Label: "FieldOffset", Value: Field.getFieldOffset());
498 W->printString(Label: "Name", Value: Field.getName());
499 return Error::success();
500}
501
502Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
503 StaticDataMemberRecord &Field) {
504 printMemberAttributes(Access: Field.getAccess(), Kind: MethodKind::Vanilla,
505 Options: MethodOptions::None);
506 printTypeIndex(FieldName: "Type", TI: Field.getType());
507 W->printString(Label: "Name", Value: Field.getName());
508 return Error::success();
509}
510
511Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
512 VFPtrRecord &VFTable) {
513 printTypeIndex(FieldName: "Type", TI: VFTable.getType());
514 return Error::success();
515}
516
517Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
518 EnumeratorRecord &Enum) {
519 printMemberAttributes(Access: Enum.getAccess(), Kind: MethodKind::Vanilla,
520 Options: MethodOptions::None);
521 W->printNumber(Label: "EnumValue", Value: Enum.getValue());
522 W->printString(Label: "Name", Value: Enum.getName());
523 return Error::success();
524}
525
526Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
527 BaseClassRecord &Base) {
528 printMemberAttributes(Access: Base.getAccess(), Kind: MethodKind::Vanilla,
529 Options: MethodOptions::None);
530 printTypeIndex(FieldName: "BaseType", TI: Base.getBaseType());
531 W->printHex(Label: "BaseOffset", Value: Base.getBaseOffset());
532 return Error::success();
533}
534
535Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
536 VirtualBaseClassRecord &Base) {
537 printMemberAttributes(Access: Base.getAccess(), Kind: MethodKind::Vanilla,
538 Options: MethodOptions::None);
539 printTypeIndex(FieldName: "BaseType", TI: Base.getBaseType());
540 printTypeIndex(FieldName: "VBPtrType", TI: Base.getVBPtrType());
541 W->printHex(Label: "VBPtrOffset", Value: Base.getVBPtrOffset());
542 W->printHex(Label: "VBTableIndex", Value: Base.getVTableIndex());
543 return Error::success();
544}
545
546Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
547 ListContinuationRecord &Cont) {
548 printTypeIndex(FieldName: "ContinuationIndex", TI: Cont.getContinuationIndex());
549 return Error::success();
550}
551
552Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) {
553 W->printEnum(Label: "Mode", Value: uint16_t(LR.Mode), EnumValues: ArrayRef(LabelTypeEnum));
554 return Error::success();
555}
556
557Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
558 PrecompRecord &Precomp) {
559 W->printHex(Label: "StartIndex", Value: Precomp.getStartTypeIndex());
560 W->printHex(Label: "Count", Value: Precomp.getTypesCount());
561 W->printHex(Label: "Signature", Value: Precomp.getSignature());
562 W->printString(Label: "PrecompFile", Value: Precomp.getPrecompFilePath());
563 return Error::success();
564}
565
566Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
567 EndPrecompRecord &EndPrecomp) {
568 W->printHex(Label: "Signature", Value: EndPrecomp.getSignature());
569 return Error::success();
570}
571

source code of llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp