• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- TypeDumper.h - CodeView type info dumper ----------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
11 #define LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
12 
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/StringSet.h"
15 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
16 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
17 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
18 
19 namespace llvm {
20 class ScopedPrinter;
21 
22 namespace codeview {
23 
24 /// Dumper for CodeView type streams found in COFF object files and PDB files.
25 class CVTypeDumper : public TypeVisitorCallbacks {
26 public:
CVTypeDumper(ScopedPrinter * W,bool PrintRecordBytes)27   CVTypeDumper(ScopedPrinter *W, bool PrintRecordBytes)
28       : W(W), PrintRecordBytes(PrintRecordBytes) {}
29 
30   StringRef getTypeName(TypeIndex TI);
31   void printTypeIndex(StringRef FieldName, TypeIndex TI);
32 
33   /// Dumps one type record.  Returns false if there was a type parsing error,
34   /// and true otherwise.  This should be called in order, since the dumper
35   /// maintains state about previous records which are necessary for cross
36   /// type references.
37   Error dump(const CVRecord<TypeLeafKind> &Record);
38 
39   /// Dumps the type records in Types. Returns false if there was a type stream
40   /// parse error, and true otherwise.
41   Error dump(const CVTypeArray &Types);
42 
43   /// Dumps the type records in Data. Returns false if there was a type stream
44   /// parse error, and true otherwise. Use this method instead of the
45   /// CVTypeArray overload when type records are laid out contiguously in
46   /// memory.
47   Error dump(ArrayRef<uint8_t> Data);
48 
49   /// Gets the type index for the next type record.
getNextTypeIndex()50   unsigned getNextTypeIndex() const {
51     return 0x1000 + CVUDTNames.size();
52   }
53 
54   /// Records the name of a type, and reserves its type index.
recordType(StringRef Name)55   void recordType(StringRef Name) { CVUDTNames.push_back(Name); }
56 
57   /// Saves the name in a StringSet and creates a stable StringRef.
saveName(StringRef TypeName)58   StringRef saveName(StringRef TypeName) {
59     return TypeNames.insert(TypeName).first->getKey();
60   }
61 
62   void setPrinter(ScopedPrinter *P);
getPrinter()63   ScopedPrinter *getPrinter() { return W; }
64 
65   /// Action to take on unknown types. By default, they are ignored.
66   Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
67   Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override;
68 
69   /// Paired begin/end actions for all types. Receives all record data,
70   /// including the fixed-length record prefix.
71   Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
72   Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
73 
74 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
75   Error visit##Name(Name##Record &Record) override;
76 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
77   TYPE_RECORD(EnumName, EnumVal, Name)
78 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
79 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
80 #include "TypeRecords.def"
81 
82 private:
83   void printMemberAttributes(MemberAttributes Attrs);
84   void printMemberAttributes(MemberAccess Access, MethodKind Kind,
85                              MethodOptions Options);
86 
87   ScopedPrinter *W;
88 
89   bool PrintRecordBytes = false;
90 
91   /// Name of the current type. Only valid before visitTypeEnd.
92   StringRef Name;
93 
94   /// All user defined type records in .debug$T live in here. Type indices
95   /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
96   /// index into this vector.
97   SmallVector<StringRef, 10> CVUDTNames;
98 
99   StringSet<> TypeNames;
100 };
101 
102 } // end namespace codeview
103 } // end namespace llvm
104 
105 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
106