LLVM  4.0.0
TypeDumpVisitor.cpp
Go to the documentation of this file.
1 //===-- TypeDumpVisitor.cpp - CodeView type info dumper -----------*- C++
2 //-*-===//
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
12 
13 #include "llvm/ADT/SmallString.h"
24 
25 using namespace llvm;
26 using namespace llvm::codeview;
27 
29 #define CV_TYPE(enum, val) {#enum, enum},
30 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
31 };
32 
33 #define ENUM_ENTRY(enum_class, enum) \
34  { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
35 
49 };
50 
54 };
55 
57  ENUM_ENTRY(MethodOptions, Pseudo),
62 };
63 
67  ENUM_ENTRY(MethodKind, Static),
72 };
73 
74 static const EnumEntry<uint8_t> PtrKindNames[] = {
88 };
89 
90 static const EnumEntry<uint8_t> PtrModeNames[] = {
96 };
97 
108 };
109 
113 };
114 
140 };
141 
146 };
147 
148 #undef ENUM_ENTRY
149 
151  switch (LT) {
152 #define TYPE_RECORD(ename, value, name) \
153  case ename: \
154  return #name;
155 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
156  default:
157  break;
158  }
159  return "UnknownLeaf";
160 }
161 
163  CVTypeDumper::printTypeIndex(*W, FieldName, TI, TypeDB);
164 }
165 
167  W->startLine() << getLeafTypeName(Record.Type);
168  W->getOStream() << " (" << HexNumber(TypeDB.getNextTypeIndex().getIndex())
169  << ")";
170  W->getOStream() << " {\n";
171  W->indent();
172  W->printEnum("TypeLeafKind", unsigned(Record.Type),
174  return Error::success();
175 }
176 
178  if (PrintRecordBytes)
179  W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));
180 
181  W->unindent();
182  W->startLine() << "}\n";
183  return Error::success();
184 }
185 
187  W->startLine() << getLeafTypeName(Record.Kind);
188  W->getOStream() << " {\n";
189  W->indent();
190  W->printEnum("TypeLeafKind", unsigned(Record.Kind),
192  return Error::success();
193 }
194 
196  if (PrintRecordBytes)
197  W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
198 
199  W->unindent();
200  W->startLine() << "}\n";
201  return Error::success();
202 }
203 
205  FieldListRecord &FieldList) {
206  CVTypeVisitor Visitor(*this);
207  if (auto EC = Visitor.visitFieldListMemberStream(FieldList.Data))
208  return EC;
209 
210  return Error::success();
211 }
212 
214  printTypeIndex("Id", String.getId());
215  W->printString("StringData", String.getString());
216  return Error::success();
217 }
218 
220  auto Indices = Args.getIndices();
221  uint32_t Size = Indices.size();
222  W->printNumber("NumArgs", Size);
223  ListScope Arguments(*W, "Arguments");
224  for (uint32_t I = 0; I < Size; ++I) {
225  printTypeIndex("ArgType", Indices[I]);
226  }
227  return Error::success();
228 }
229 
231  uint16_t Props = static_cast<uint16_t>(Class.getOptions());
232  W->printNumber("MemberCount", Class.getMemberCount());
233  W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
234  printTypeIndex("FieldList", Class.getFieldList());
235  printTypeIndex("DerivedFrom", Class.getDerivationList());
236  printTypeIndex("VShape", Class.getVTableShape());
237  W->printNumber("SizeOf", Class.getSize());
238  W->printString("Name", Class.getName());
239  if (Props & uint16_t(ClassOptions::HasUniqueName))
240  W->printString("LinkageName", Class.getUniqueName());
241  return Error::success();
242 }
243 
245  uint16_t Props = static_cast<uint16_t>(Union.getOptions());
246  W->printNumber("MemberCount", Union.getMemberCount());
247  W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
248  printTypeIndex("FieldList", Union.getFieldList());
249  W->printNumber("SizeOf", Union.getSize());
250  W->printString("Name", Union.getName());
251  if (Props & uint16_t(ClassOptions::HasUniqueName))
252  W->printString("LinkageName", Union.getUniqueName());
253  return Error::success();
254 }
255 
257  uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
258  W->printNumber("NumEnumerators", Enum.getMemberCount());
259  W->printFlags("Properties", uint16_t(Enum.getOptions()),
261  printTypeIndex("UnderlyingType", Enum.getUnderlyingType());
262  printTypeIndex("FieldListType", Enum.getFieldList());
263  W->printString("Name", Enum.getName());
264  if (Props & uint16_t(ClassOptions::HasUniqueName))
265  W->printString("LinkageName", Enum.getUniqueName());
266  return Error::success();
267 }
268 
270  printTypeIndex("ElementType", AT.getElementType());
271  printTypeIndex("IndexType", AT.getIndexType());
272  W->printNumber("SizeOf", AT.getSize());
273  W->printString("Name", AT.getName());
274  return Error::success();
275 }
276 
278  printTypeIndex("CompleteClass", VFT.getCompleteClass());
279  printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
280  W->printHex("VFPtrOffset", VFT.getVFPtrOffset());
281  W->printString("VFTableName", VFT.getName());
282  for (auto N : VFT.getMethodNames())
283  W->printString("MethodName", N);
284  return Error::success();
285 }
286 
288  printTypeIndex("ClassType", Id.getClassType());
289  printTypeIndex("FunctionType", Id.getFunctionType());
290  W->printString("Name", Id.getName());
291  return Error::success();
292 }
293 
295  printTypeIndex("ReturnType", Proc.getReturnType());
296  W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
298  W->printFlags("FunctionOptions", uint8_t(Proc.getOptions()),
300  W->printNumber("NumParameters", Proc.getParameterCount());
301  printTypeIndex("ArgListType", Proc.getArgumentList());
302  return Error::success();
303 }
304 
306  printTypeIndex("ReturnType", MF.getReturnType());
307  printTypeIndex("ClassType", MF.getClassType());
308  printTypeIndex("ThisType", MF.getThisType());
309  W->printEnum("CallingConvention", uint8_t(MF.getCallConv()),
311  W->printFlags("FunctionOptions", uint8_t(MF.getOptions()),
313  W->printNumber("NumParameters", MF.getParameterCount());
314  printTypeIndex("ArgListType", MF.getArgumentList());
315  W->printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
316  return Error::success();
317 }
318 
320  MethodOverloadListRecord &MethodList) {
321  for (auto &M : MethodList.getMethods()) {
322  ListScope S(*W, "Method");
323  printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions());
324  printTypeIndex("Type", M.getType());
325  if (M.isIntroducingVirtual())
326  W->printHex("VFTableOffset", M.getVFTableOffset());
327  }
328  return Error::success();
329 }
330 
332  printTypeIndex("ParentScope", Func.getParentScope());
333  printTypeIndex("FunctionType", Func.getFunctionType());
334  W->printString("Name", Func.getName());
335  return Error::success();
336 }
337 
339  W->printBinary("Signature", TS.getGuid());
340  W->printNumber("Age", TS.getAge());
341  W->printString("Name", TS.getName());
342  return Error::success();
343 }
344 
346  printTypeIndex("PointeeType", Ptr.getReferentType());
347  W->printHex("PointerAttributes", uint32_t(Ptr.getOptions()));
348  W->printEnum("PtrType", unsigned(Ptr.getPointerKind()),
350  W->printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames));
351 
352  W->printNumber("IsFlat", Ptr.isFlat());
353  W->printNumber("IsConst", Ptr.isConst());
354  W->printNumber("IsVolatile", Ptr.isVolatile());
355  W->printNumber("IsUnaligned", Ptr.isUnaligned());
356  W->printNumber("SizeOf", Ptr.getSize());
357 
358  if (Ptr.isPointerToMember()) {
359  const MemberPointerInfo &MI = Ptr.getMemberInfo();
360 
361  printTypeIndex("ClassType", MI.getContainingType());
362  W->printEnum("Representation", uint16_t(MI.getRepresentation()),
364  }
365 
366  return Error::success();
367 }
368 
370  uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
371  printTypeIndex("ModifiedType", Mod.getModifiedType());
372  W->printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
373 
374  return Error::success();
375 }
376 
378  printTypeIndex("Type", BitField.getType());
379  W->printNumber("BitSize", BitField.getBitSize());
380  W->printNumber("BitOffset", BitField.getBitOffset());
381  return Error::success();
382 }
383 
385  VFTableShapeRecord &Shape) {
386  W->printNumber("VFEntryCount", Shape.getEntryCount());
387  return Error::success();
388 }
389 
392  printTypeIndex("UDT", Line.getUDT());
393  printTypeIndex("SourceFile", Line.getSourceFile());
394  W->printNumber("LineNumber", Line.getLineNumber());
395  return Error::success();
396 }
397 
399  UdtModSourceLineRecord &Line) {
400  printTypeIndex("UDT", Line.getUDT());
401  printTypeIndex("SourceFile", Line.getSourceFile());
402  W->printNumber("LineNumber", Line.getLineNumber());
403  W->printNumber("Module", Line.getModule());
404  return Error::success();
405 }
406 
408  W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
409 
410  ListScope Arguments(*W, "Arguments");
411  for (auto Arg : Args.getArgs()) {
412  printTypeIndex("ArgType", Arg);
413  }
414  return Error::success();
415 }
416 
417 void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs) {
418  return printMemberAttributes(Attrs.getAccess(), Attrs.getMethodKind(),
419  Attrs.getFlags());
420 }
421 
422 void TypeDumpVisitor::printMemberAttributes(MemberAccess Access,
424  MethodOptions Options) {
425  W->printEnum("AccessSpecifier", uint8_t(Access),
427  // Data members will be vanilla. Don't try to print a method kind for them.
428  if (Kind != MethodKind::Vanilla)
429  W->printEnum("MethodKind", unsigned(Kind), makeArrayRef(MemberKindNames));
430  if (Options != MethodOptions::None) {
431  W->printFlags("MethodOptions", unsigned(Options),
433  }
434 }
435 
437  W->printHex("UnknownMember", unsigned(Record.Kind));
438  return Error::success();
439 }
440 
442  W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames));
443  W->printNumber("Length", uint32_t(Record.content().size()));
444  return Error::success();
445 }
446 
448  NestedTypeRecord &Nested) {
449  printTypeIndex("Type", Nested.getNestedType());
450  W->printString("Name", Nested.getName());
451  return Error::success();
452 }
453 
455  OneMethodRecord &Method) {
456  MethodKind K = Method.getMethodKind();
457  printMemberAttributes(Method.getAccess(), K, Method.getOptions());
458  printTypeIndex("Type", Method.getType());
459  // If virtual, then read the vftable offset.
460  if (Method.isIntroducingVirtual())
461  W->printHex("VFTableOffset", Method.getVFTableOffset());
462  W->printString("Name", Method.getName());
463  return Error::success();
464 }
465 
467  OverloadedMethodRecord &Method) {
468  W->printHex("MethodCount", Method.getNumOverloads());
469  printTypeIndex("MethodListIndex", Method.getMethodList());
470  W->printString("Name", Method.getName());
471  return Error::success();
472 }
473 
476  printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
478  printTypeIndex("Type", Field.getType());
479  W->printHex("FieldOffset", Field.getFieldOffset());
480  W->printString("Name", Field.getName());
481  return Error::success();
482 }
483 
485  StaticDataMemberRecord &Field) {
486  printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
488  printTypeIndex("Type", Field.getType());
489  W->printString("Name", Field.getName());
490  return Error::success();
491 }
492 
494  VFPtrRecord &VFTable) {
495  printTypeIndex("Type", VFTable.getType());
496  return Error::success();
497 }
498 
500  EnumeratorRecord &Enum) {
501  printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
503  W->printNumber("EnumValue", Enum.getValue());
504  W->printString("Name", Enum.getName());
505  return Error::success();
506 }
507 
509  BaseClassRecord &Base) {
510  printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
512  printTypeIndex("BaseType", Base.getBaseType());
513  W->printHex("BaseOffset", Base.getBaseOffset());
514  return Error::success();
515 }
516 
518  VirtualBaseClassRecord &Base) {
519  printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
521  printTypeIndex("BaseType", Base.getBaseType());
522  printTypeIndex("VBPtrType", Base.getVBPtrType());
523  W->printHex("VBPtrOffset", Base.getVBPtrOffset());
524  W->printHex("VBTableIndex", Base.getVTableIndex());
525  return Error::success();
526 }
527 
529  ListContinuationRecord &Cont) {
530  printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
531  return Error::success();
532 }
const NoneType None
Definition: None.h:23
PointerKind
Equivalent to CV_ptrtype_e.
Definition: CodeView.h:309
CallingConvention getCallConv() const
Definition: TypeRecord.h:203
static const EnumEntry< uint8_t > PtrKindNames[]
void printEnum(StringRef Label, T Value, ArrayRef< EnumEntry< TEnum >> EnumValues)
Definition: ScopedPrinter.h:94
StringRef getName() const
Definition: TypeRecord.h:364
TypeIndex getBaseType() const
Definition: TypeRecord.h:894
TypeIndex getArgumentList() const
Definition: TypeRecord.h:172
TypeIndex getSourceFile() const
Definition: TypeRecord.h:637
MethodKind getMethodKind() const
Definition: TypeRecord.h:733
static const EnumEntry< uint8_t > PtrModeNames[]
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:28
ArrayRef< uint8_t > Data
Definition: TypeRecord.h:43
Error visitTypeEnd(CVType &Record) override
MethodOptions getFlags() const
Get the flags that are not included in access control or method properties.
Definition: TypeRecord.h:78
MethodOptions getOptions() const
Definition: TypeRecord.h:734
ArrayRef< TypeIndex > getArgs() const
Definition: TypeRecord.h:679
static const EnumEntry< uint8_t > FunctionOptionEnum[]
TypeIndex getElementType() const
Definition: TypeRecord.h:397
ArrayRef< uint8_t > Data
Definition: TypeRecord.h:381
TypeIndex getNextTypeIndex() const
Gets the type index for the next type record.
TypeIndex getFunctionType() const
Definition: TypeRecord.h:233
TypeIndex getOverriddenVTable() const
Definition: TypeRecord.h:701
CallingConvention getCallConv() const
Definition: TypeRecord.h:169
TypeIndex getId() const
Definition: TypeRecord.h:594
Error visitUnknownType(CVType &Record) override
Action to take on unknown types. By default, they are ignored.
uint64_t getBaseOffset() const
Definition: TypeRecord.h:895
static const EnumEntry< uint16_t > ClassOptionNames[]
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
void indent(int Levels=1)
Definition: ScopedPrinter.h:75
MemberAccess getAccess() const
Definition: TypeRecord.h:893
StringRef getString() const
Definition: TypeRecord.h:596
bool isPointerToMember() const
Definition: TypeRecord.h:319
StringRef getName() const
Definition: TypeRecord.h:400
static const EnumEntry< uint16_t > MemberKindNames[]
bool isIntroducingVirtual() const
Definition: TypeRecord.h:739
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
TypeIndex getParentScope() const
Definition: TypeRecord.h:613
raw_ostream & getOStream()
TypeIndex getContainingType() const
Definition: TypeRecord.h:113
ModifierOptions
Equivalent to CV_modifier_t.
Definition: CodeView.h:280
void printBinary(StringRef Label, StringRef Str, ArrayRef< uint8_t > Value)
uint16_t getMemberCount() const
Definition: TypeRecord.h:430
static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks)
A 32-bit type reference.
Definition: TypeIndex.h:89
TypeIndex getFunctionType() const
Definition: TypeRecord.h:615
uint16_t getParameterCount() const
Definition: TypeRecord.h:171
MemberAccess getAccess() const
Definition: TypeRecord.h:853
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Definition: CodeView.h:255
Kind kind() const
Definition: CVRecord.h:33
StringRef getName() const
Definition: TypeRecord.h:806
TypeIndex getReturnType() const
Definition: TypeRecord.h:168
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
#define ENUM_ENTRY(enum_class, enum)
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
StringRef getName() const
Definition: TypeRecord.h:737
uint32_t getIndex() const
Definition: TypeIndex.h:103
TypeIndex getContinuationIndex() const
Definition: TypeRecord.h:943
static StringRef getLeafTypeName(TypeLeafKind LT)
PointerToMemberRepresentation getRepresentation() const
Definition: TypeRecord.h:114
static Error visitKnownMember(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks)
raw_ostream & startLine()
StringRef getName() const
Definition: TypeRecord.h:855
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
Definition: TypeRecord.h:936
TypeIndex getType() const
Definition: TypeRecord.h:732
uint8_t getSize() const
Definition: TypeRecord.h:313
TypeIndex getType() const
Definition: TypeRecord.h:804
ArrayRef< OneMethodRecord > getMethods() const
Definition: TypeRecord.h:761
For method overload sets. LF_METHOD.
Definition: TypeRecord.h:766
StringRef getName() const
Definition: TypeRecord.h:703
uint8_t getBitSize() const
Definition: TypeRecord.h:530
void printHex(StringRef Label, T Value)
FunctionOptions getOptions() const
Definition: TypeRecord.h:204
ArrayRef< StringRef > getMethodNames() const
Definition: TypeRecord.h:704
MemberAccess getAccess() const
Get the access specifier. Valid for any kind of member.
Definition: TypeRecord.h:65
uint64_t getSize() const
Definition: TypeRecord.h:472
ModifierOptions getModifiers() const
Definition: TypeRecord.h:147
ClassOptions getOptions() const
Definition: TypeRecord.h:431
void printString(StringRef Value)
static ErrorSuccess success()
Create a success value.
void printNumber(StringRef Label, uint64_t Value)
uint64_t getSize() const
Definition: TypeRecord.h:494
TypeIndex getCompleteClass() const
Definition: TypeRecord.h:700
Error visitUnknownMember(CVMemberRecord &Record) override
static const EnumEntry< uint16_t > PtrMemberRepNames[]
TypeIndex getIndexType() const
Definition: TypeRecord.h:398
ArrayRef< uint8_t > content() const
Definition: CVRecord.h:36
TypeIndex getClassType() const
Definition: TypeRecord.h:232
void printTypeIndex(StringRef FieldName, TypeIndex TI) const
MemberAccess getAccess() const
Definition: TypeRecord.h:803
PointerMode getMode() const
Definition: TypeRecord.h:304
MethodKind getMethodKind() const
Indicates if a method is defined with friend, virtual, static, etc.
Definition: TypeRecord.h:70
Error visitMemberBegin(CVMemberRecord &Record) override
static const EnumEntry< uint8_t > CallingConventions[]
PointerMode
Equivalent to CV_ptrmode_e.
Definition: CodeView.h:326
TypeIndex getVTableShape() const
Definition: TypeRecord.h:471
static const EnumEntry< uint16_t > MethodOptionNames[]
MethodOptions
Equivalent to CV_fldattr_t bitfield.
Definition: CodeView.h:266
StringRef getBytesAsCharacters(ArrayRef< uint8_t > LeafData)
Reinterpret a byte array as an array of characters.
TypeIndex getFieldList() const
Definition: TypeRecord.h:432
void unindent(int Levels=1)
Definition: ScopedPrinter.h:77
TypeIndex getModifiedType() const
Definition: TypeRecord.h:146
static const EnumEntry< uint16_t > TypeModifierNames[]
static const EnumEntry< uint8_t > MemberAccessNames[]
ArrayRef< TypeIndex > getIndices() const
Definition: TypeRecord.h:252
TypeIndex getArgumentList() const
Definition: TypeRecord.h:206
StringRef getName() const
Definition: TypeRecord.h:433
void printFlags(StringRef Label, T Value, ArrayRef< EnumEntry< TFlag >> Flags, TFlag EnumMask1={}, TFlag EnumMask2={}, TFlag EnumMask3={})
FunctionOptions getOptions() const
Definition: TypeRecord.h:170
uint32_t getVFPtrOffset() const
Definition: TypeRecord.h:702
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
MemberPointerInfo getMemberInfo() const
Definition: TypeRecord.h:317
static void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeDatabase &DB)
TypeIndex getType() const
Definition: TypeRecord.h:528
TypeIndex getNestedType() const
Definition: TypeRecord.h:363
PointerToMemberRepresentation
Equivalent to CV_pmtype_e.
Definition: CodeView.h:347
PointerKind getPointerKind() const
Definition: TypeRecord.h:299
const unsigned Kind
MemberAccess
Source-level access specifier. (CV_access_e)
Definition: CodeView.h:247
uint64_t getSize() const
Definition: TypeRecord.h:399
uint64_t getFieldOffset() const
Definition: TypeRecord.h:805
uint8_t getBitOffset() const
Definition: TypeRecord.h:529
Equvalent to CV_fldattr_t in cvinfo.h.
Definition: TypeRecord.h:48
Lightweight error class with error context and mandatory checking.
CallingConvention
These values correspond to the CV_call_e enumeration, and are documented at the following locations: ...
Definition: CodeView.h:162
Error visitMemberEnd(CVMemberRecord &Record) override
PointerOptions getOptions() const
Definition: TypeRecord.h:309
static TraceState * TS
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
TypeIndex getUnderlyingType() const
Definition: TypeRecord.h:512
StringRef getUniqueName() const
Definition: TypeRecord.h:434
int * Ptr
int32_t getVFTableOffset() const
Definition: TypeRecord.h:736
TypeIndex getType() const
Definition: TypeRecord.h:873
MemberAccess getAccess() const
Definition: TypeRecord.h:735
int32_t getThisPointerAdjustment() const
Definition: TypeRecord.h:207
TypeIndex getDerivationList() const
Definition: TypeRecord.h:470
TypeIndex getReferentType() const
Definition: TypeRecord.h:297
StringRef getName() const
Definition: TypeRecord.h:617
void printBinaryBlock(StringRef Label, ArrayRef< uint8_t > Value)