LLVM 23.0.0git
TypeDumpVisitor.cpp
Go to the documentation of this file.
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
10
11#include "llvm/ADT/ArrayRef.h"
21
22using namespace llvm;
23using namespace llvm::codeview;
24
26 switch (LT) {
27#define TYPE_RECORD(ename, value, name) \
28 case ename: \
29 return #name;
30#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
31 default:
32 break;
33 }
34 return "UnknownLeaf";
35}
36
38 codeview::printTypeIndex(*W, FieldName, TI, TpiTypes);
39}
40
42 codeview::printTypeIndex(*W, FieldName, TI, getSourceTypes());
43}
44
48
50 W->startLine() << getLeafTypeName(Record.kind());
51 W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
52 W->getOStream() << " {\n";
53 W->indent();
54 W->printEnum("TypeLeafKind", unsigned(Record.kind()), getTypeLeafNames());
55 return Error::success();
56}
57
59 if (PrintRecordBytes)
60 W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));
61
62 W->unindent();
63 W->startLine() << "}\n";
64 return Error::success();
65}
66
68 W->startLine() << getLeafTypeName(Record.Kind);
69 W->getOStream() << " {\n";
70 W->indent();
71 W->printEnum("TypeLeafKind", unsigned(Record.Kind), getTypeLeafNames());
72 return Error::success();
73}
74
76 if (PrintRecordBytes)
77 W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
78
79 W->unindent();
80 W->startLine() << "}\n";
81 return Error::success();
82}
83
84Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
86 if (auto EC = codeview::visitMemberRecordStream(FieldList.Data, *this))
87 return EC;
88
89 return Error::success();
90}
91
92Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringIdRecord &String) {
93 printItemIndex("Id", String.getId());
94 W->printString("StringData", String.getString());
95 return Error::success();
96}
97
98Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
99 auto Indices = Args.getIndices();
100 uint32_t Size = Indices.size();
101 W->printNumber("NumArgs", Size);
102 ListScope Arguments(*W, "Arguments");
103 for (uint32_t I = 0; I < Size; ++I) {
104 printTypeIndex("ArgType", Indices[I]);
105 }
106 return Error::success();
107}
108
109Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringListRecord &Strs) {
110 auto Indices = Strs.getIndices();
111 uint32_t Size = Indices.size();
112 W->printNumber("NumStrings", Size);
113 ListScope Arguments(*W, "Strings");
114 for (uint32_t I = 0; I < Size; ++I) {
115 printItemIndex("String", Indices[I]);
116 }
117 return Error::success();
118}
119
120Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
121 uint16_t Props = static_cast<uint16_t>(Class.getOptions());
122 W->printNumber("MemberCount", Class.getMemberCount());
123 W->printFlags("Properties", Props, getClassOptionNames());
124 printTypeIndex("FieldList", Class.getFieldList());
125 printTypeIndex("DerivedFrom", Class.getDerivationList());
126 printTypeIndex("VShape", Class.getVTableShape());
127 W->printNumber("SizeOf", Class.getSize());
128 W->printString("Name", Class.getName());
129 if (Props & uint16_t(ClassOptions::HasUniqueName))
130 W->printString("LinkageName", Class.getUniqueName());
131 return Error::success();
132}
133
134Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
135 uint16_t Props = static_cast<uint16_t>(Union.getOptions());
136 W->printNumber("MemberCount", Union.getMemberCount());
137 W->printFlags("Properties", Props, getClassOptionNames());
138 printTypeIndex("FieldList", Union.getFieldList());
139 W->printNumber("SizeOf", Union.getSize());
140 W->printString("Name", Union.getName());
141 if (Props & uint16_t(ClassOptions::HasUniqueName))
142 W->printString("LinkageName", Union.getUniqueName());
143 return Error::success();
144}
145
146Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
147 uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
148 W->printNumber("NumEnumerators", Enum.getMemberCount());
149 W->printFlags("Properties", uint16_t(Enum.getOptions()),
151 printTypeIndex("UnderlyingType", Enum.getUnderlyingType());
152 printTypeIndex("FieldListType", Enum.getFieldList());
153 W->printString("Name", Enum.getName());
154 if (Props & uint16_t(ClassOptions::HasUniqueName))
155 W->printString("LinkageName", Enum.getUniqueName());
156 return Error::success();
157}
158
159Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
160 printTypeIndex("ElementType", AT.getElementType());
161 printTypeIndex("IndexType", AT.getIndexType());
162 W->printNumber("SizeOf", AT.getSize());
163 W->printString("Name", AT.getName());
164 return Error::success();
165}
166
167Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
168 printTypeIndex("CompleteClass", VFT.getCompleteClass());
169 printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
170 W->printHex("VFPtrOffset", VFT.getVFPtrOffset());
171 W->printString("VFTableName", VFT.getName());
172 for (auto N : VFT.getMethodNames())
173 W->printString("MethodName", N);
174 return Error::success();
175}
176
177Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
178 printTypeIndex("ClassType", Id.getClassType());
179 printTypeIndex("FunctionType", Id.getFunctionType());
180 W->printString("Name", Id.getName());
181 return Error::success();
182}
183
184Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
185 printTypeIndex("ReturnType", Proc.getReturnType());
186 W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
188 W->printFlags("FunctionOptions", uint8_t(Proc.getOptions()),
190 W->printNumber("NumParameters", Proc.getParameterCount());
191 printTypeIndex("ArgListType", Proc.getArgumentList());
192 return Error::success();
193}
194
195Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFunctionRecord &MF) {
196 printTypeIndex("ReturnType", MF.getReturnType());
197 printTypeIndex("ClassType", MF.getClassType());
198 printTypeIndex("ThisType", MF.getThisType());
199 W->printEnum("CallingConvention", uint8_t(MF.getCallConv()),
201 W->printFlags("FunctionOptions", uint8_t(MF.getOptions()),
203 W->printNumber("NumParameters", MF.getParameterCount());
204 printTypeIndex("ArgListType", MF.getArgumentList());
205 W->printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
206 return Error::success();
207}
208
209Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
210 MethodOverloadListRecord &MethodList) {
211 for (const auto &M : MethodList.getMethods()) {
212 ListScope S(*W, "Method");
213 printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions());
214 printTypeIndex("Type", M.getType());
215 if (M.isIntroducingVirtual())
216 W->printHex("VFTableOffset", M.getVFTableOffset());
217 }
218 return Error::success();
219}
220
221Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
222 printItemIndex("ParentScope", Func.getParentScope());
223 printTypeIndex("FunctionType", Func.getFunctionType());
224 W->printString("Name", Func.getName());
225 return Error::success();
226}
227
228Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
229 W->printString("Guid", formatv("{0}", TS.getGuid()).str());
230 W->printNumber("Age", TS.getAge());
231 W->printString("Name", TS.getName());
232 return Error::success();
233}
234
235Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
236 printTypeIndex("PointeeType", Ptr.getReferentType());
237 W->printEnum("PtrType", unsigned(Ptr.getPointerKind()), getPtrKindNames());
238 W->printEnum("PtrMode", unsigned(Ptr.getMode()), getPtrModeNames());
239
240 W->printNumber("IsFlat", Ptr.isFlat());
241 W->printNumber("IsConst", Ptr.isConst());
242 W->printNumber("IsVolatile", Ptr.isVolatile());
243 W->printNumber("IsUnaligned", Ptr.isUnaligned());
244 W->printNumber("IsRestrict", Ptr.isRestrict());
245 W->printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
246 W->printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
247 W->printNumber("SizeOf", Ptr.getSize());
248
249 if (Ptr.isPointerToMember()) {
250 const MemberPointerInfo &MI = Ptr.getMemberInfo();
251
252 printTypeIndex("ClassType", MI.getContainingType());
253 W->printEnum("Representation", uint16_t(MI.getRepresentation()),
255 }
256
257 return Error::success();
258}
259
260Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
261 uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
262 printTypeIndex("ModifiedType", Mod.getModifiedType());
263 W->printFlags("Modifiers", Mods, getTypeModifierNames());
264
265 return Error::success();
266}
267
268Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BitFieldRecord &BitField) {
269 printTypeIndex("Type", BitField.getType());
270 W->printNumber("BitSize", BitField.getBitSize());
271 W->printNumber("BitOffset", BitField.getBitOffset());
272 return Error::success();
273}
274
275Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
276 VFTableShapeRecord &Shape) {
277 W->printNumber("VFEntryCount", Shape.getEntryCount());
278 return Error::success();
279}
280
281Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
283 printTypeIndex("UDT", Line.getUDT());
284 printItemIndex("SourceFile", Line.getSourceFile());
285 W->printNumber("LineNumber", Line.getLineNumber());
286 return Error::success();
287}
288
289Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
291 printTypeIndex("UDT", Line.getUDT());
292 printItemIndex("SourceFile", Line.getSourceFile());
293 W->printNumber("LineNumber", Line.getLineNumber());
294 W->printNumber("Module", Line.getModule());
295 return Error::success();
296}
297
298Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &Args) {
299 W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
300
301 ListScope Arguments(*W, "Arguments");
302 for (auto Arg : Args.getArgs()) {
303 printItemIndex("ArgType", Arg);
304 }
305 return Error::success();
306}
307
308void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs) {
309 return printMemberAttributes(Attrs.getAccess(), Attrs.getMethodKind(),
310 Attrs.getFlags());
311}
312
313void TypeDumpVisitor::printMemberAttributes(MemberAccess Access,
314 MethodKind Kind,
316 W->printEnum("AccessSpecifier", uint8_t(Access), getMemberAccessNames());
317 // Data members will be vanilla. Don't try to print a method kind for them.
318 if (Kind != MethodKind::Vanilla)
319 W->printEnum("MethodKind", unsigned(Kind), getMemberKindNames());
321 W->printFlags("MethodOptions", unsigned(Options), getMethodOptionNames());
322 }
323}
324
326 W->printHex("UnknownMember", unsigned(Record.Kind));
327 return Error::success();
328}
329
331 W->printEnum("Kind", uint16_t(Record.kind()), getTypeLeafNames());
332 W->printNumber("Length", uint32_t(Record.content().size()));
333 return Error::success();
334}
335
336Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
338 printTypeIndex("Type", Nested.getNestedType());
339 W->printString("Name", Nested.getName());
340 return Error::success();
341}
342
343Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
344 OneMethodRecord &Method) {
345 MethodKind K = Method.getMethodKind();
346 printMemberAttributes(Method.getAccess(), K, Method.getOptions());
347 printTypeIndex("Type", Method.getType());
348 // If virtual, then read the vftable offset.
349 if (Method.isIntroducingVirtual())
350 W->printHex("VFTableOffset", Method.getVFTableOffset());
351 W->printString("Name", Method.getName());
352 return Error::success();
353}
354
355Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
356 OverloadedMethodRecord &Method) {
357 W->printHex("MethodCount", Method.getNumOverloads());
358 printTypeIndex("MethodListIndex", Method.getMethodList());
359 W->printString("Name", Method.getName());
360 return Error::success();
361}
362
363Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
365 printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
367 printTypeIndex("Type", Field.getType());
368 W->printHex("FieldOffset", Field.getFieldOffset());
369 W->printString("Name", Field.getName());
370 return Error::success();
371}
372
373Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
375 printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
377 printTypeIndex("Type", Field.getType());
378 W->printString("Name", Field.getName());
379 return Error::success();
380}
381
382Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
383 VFPtrRecord &VFTable) {
384 printTypeIndex("Type", VFTable.getType());
385 return Error::success();
386}
387
388Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
389 EnumeratorRecord &Enum) {
390 printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
392 W->printNumber("EnumValue", Enum.getValue());
393 W->printString("Name", Enum.getName());
394 return Error::success();
395}
396
397Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
399 printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
401 printTypeIndex("BaseType", Base.getBaseType());
402 W->printHex("BaseOffset", Base.getBaseOffset());
403 return Error::success();
404}
405
406Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
408 printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
410 printTypeIndex("BaseType", Base.getBaseType());
411 printTypeIndex("VBPtrType", Base.getVBPtrType());
412 W->printHex("VBPtrOffset", Base.getVBPtrOffset());
413 W->printHex("VBTableIndex", Base.getVTableIndex());
414 return Error::success();
415}
416
417Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
419 printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
420 return Error::success();
421}
422
423Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) {
424 W->printEnum("Mode", uint16_t(LR.Mode), getLabelTypeEnum());
425 return Error::success();
426}
427
428Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
429 PrecompRecord &Precomp) {
430 W->printHex("StartIndex", Precomp.getStartTypeIndex());
431 W->printHex("Count", Precomp.getTypesCount());
432 W->printHex("Signature", Precomp.getSignature());
433 W->printString("PrecompFile", Precomp.getPrecompFilePath());
434 return Error::success();
435}
436
437Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
438 EndPrecompRecord &EndPrecomp) {
439 W->printHex("Signature", EndPrecomp.getSignature());
440 return Error::success();
441}
AMDGPU Lower Kernel Arguments
DXIL Resource Access
IRTranslator LLVM IR MI
static LVOptions Options
Definition LVOptions.cpp:25
#define I(x, y, z)
Definition MD5.cpp:57
OptimizedStructLayoutField Field
static StringRef getLeafTypeName(TypeLeafKind LT)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
virtual void printString(StringRef Value)
virtual void printNumber(StringRef Label, char Value)
void printHex(StringRef Label, T Value)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TypeIndex getElementType() const
Definition TypeRecord.h:405
TypeIndex getIndexType() const
Definition TypeRecord.h:406
uint64_t getSize() const
Definition TypeRecord.h:407
StringRef getName() const
Definition TypeRecord.h:408
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
Definition TypeRecord.h:914
FunctionOptions getOptions() const
Definition TypeRecord.h:190
CallingConvention getCallConv() const
Definition TypeRecord.h:189
ArrayRef< OneMethodRecord > getMethods() const
Definition TypeRecord.h:758
For method overload sets. LF_METHOD.
Definition TypeRecord.h:764
bool isRValueReferenceThisPtr() const
Definition TypeRecord.h:344
TypeIndex getReferentType() const
Definition TypeRecord.h:298
MemberPointerInfo getMemberInfo() const
Definition TypeRecord.h:318
bool isLValueReferenceThisPtr() const
Definition TypeRecord.h:340
PointerMode getMode() const
Definition TypeRecord.h:305
PointerKind getPointerKind() const
Definition TypeRecord.h:300
uint32_t getSignature() const
Definition TypeRecord.h:935
StringRef getPrecompFilePath() const
Definition TypeRecord.h:936
uint32_t getTypesCount() const
Definition TypeRecord.h:934
uint32_t getStartTypeIndex() const
Definition TypeRecord.h:933
TypeIndex getReturnType() const
Definition TypeRecord.h:157
TypeIndex getArgumentList() const
Definition TypeRecord.h:161
uint16_t getParameterCount() const
Definition TypeRecord.h:160
FunctionOptions getOptions() const
Definition TypeRecord.h:159
CallingConvention getCallConv() const
Definition TypeRecord.h:158
ArrayRef< TypeIndex > getIndices() const
Definition TypeRecord.h:258
Error visitTypeEnd(CVType &Record) override
void printTypeIndex(StringRef FieldName, TypeIndex TI) const
Error visitUnknownMember(CVMemberRecord &Record) override
Error visitMemberEnd(CVMemberRecord &Record) override
Error visitUnknownType(CVType &Record) override
Action to take on unknown types. By default, they are ignored.
void printItemIndex(StringRef FieldName, TypeIndex TI) const
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Error visitMemberBegin(CVMemberRecord &Record) override
A 32-bit type reference.
Definition TypeIndex.h:97
static TypeIndex fromArrayIndex(uint32_t Index)
Definition TypeIndex.h:124
const GUID & getGuid() const
Definition TypeRecord.h:585
TypeIndex getType() const
Definition TypeRecord.h:857
uint32_t getVFPtrOffset() const
Definition TypeRecord.h:705
TypeIndex getOverriddenVTable() const
Definition TypeRecord.h:704
ArrayRef< StringRef > getMethodNames() const
Definition TypeRecord.h:708
StringRef getName() const
Definition TypeRecord.h:706
TypeIndex getCompleteClass() const
Definition TypeRecord.h:703
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getMethodOptionNames()
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Definition CodeView.h:252
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getCallingConventions()
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getMemberAccessNames()
CVRecord< TypeLeafKind > CVType
Definition CVRecord.h:64
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getPtrKindNames()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getPtrMemberRepNames()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getLabelTypeEnum()
LLVM_ABI ArrayRef< EnumEntry< TypeLeafKind > > getTypeLeafNames()
LLVM_ABI Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getTypeModifierNames()
MethodOptions
Equivalent to CV_fldattr_t bitfield.
Definition CodeView.h:263
LLVM_ABI StringRef getBytesAsCharacters(ArrayRef< uint8_t > LeafData)
Reinterpret a byte array as an array of characters.
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getMemberKindNames()
MemberAccess
Source-level access specifier. (CV_access_e)
Definition CodeView.h:244
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition CodeView.h:34
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getPtrModeNames()
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getFunctionOptionEnum()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getClassOptionNames()
LLVM_ABI void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
Definition TypeIndex.cpp:93
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
#define N
Equvalent to CV_fldattr_t in cvinfo.h.
Definition TypeRecord.h:40