llvm.org GIT mirror llvm / 3361faf
[PDB] Finish and simplify TPI hashing Summary: This removes the CVTypeVisitor updater and verifier classes. They were made dead by the minimal type dumping refactoring. Replace them with a single function that takes a type record and produces a hash. Call this from the minimal type dumper and compare the hash. I also noticed that the microsoft-pdb reference repository uses a basic CRC32 for records that aren't special. We already have an implementation of that CRC ready to use, because it's used in COFF for ICF. I'll make LLD call this hashing utility in a follow-up change. We might also consider using this same hash in type stream merging, so that we don't have to hash our records twice. Reviewers: inglorion, ruiu Subscribers: llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D35515 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308240 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 3 years ago
6 changed file(s) with 149 addition(s) and 229 deletion(s). Raw diff Collapse all Expand all
99 #ifndef LLVM_DEBUGINFO_PDB_TPIHASHING_H
1010 #define LLVM_DEBUGINFO_PDB_TPIHASHING_H
1111
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/StringExtras.h"
14 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
1512 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
16 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
17 #include "llvm/DebugInfo/PDB/Native/RawError.h"
18 #include "llvm/Support/BinaryStreamArray.h"
19 #include "llvm/Support/Endian.h"
2013 #include "llvm/Support/Error.h"
21 #include
22 #include
2314
2415 namespace llvm {
2516 namespace pdb {
2617
27 class TpiHashUpdater : public codeview::TypeVisitorCallbacks {
28 public:
29 TpiHashUpdater() = default;
30
31 #define TYPE_RECORD(EnumName, EnumVal, Name) \
32 virtual Error visitKnownRecord(codeview::CVType &CVR, \
33 codeview::Name##Record &Record) override { \
34 visitKnownRecordImpl(CVR, Record); \
35 return Error::success(); \
36 }
37 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
38 #define MEMBER_RECORD(EnumName, EnumVal, Name)
39 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
40 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
41
42 private:
43 template
44 void visitKnownRecordImpl(codeview::CVType &CVR, RecordKind &Record) {
45 CVR.Hash = 0;
46 }
47
48 void visitKnownRecordImpl(codeview::CVType &CVR,
49 codeview::UdtSourceLineRecord &Rec);
50 void visitKnownRecordImpl(codeview::CVType &CVR,
51 codeview::UdtModSourceLineRecord &Rec);
52 void visitKnownRecordImpl(codeview::CVType &CVR, codeview::ClassRecord &Rec);
53 void visitKnownRecordImpl(codeview::CVType &CVR, codeview::EnumRecord &Rec);
54 void visitKnownRecordImpl(codeview::CVType &CVR, codeview::UnionRecord &Rec);
55 };
56
57 class TpiHashVerifier : public codeview::TypeVisitorCallbacks {
58 public:
59 TpiHashVerifier(FixedStreamArray &HashValues,
60 uint32_t NumHashBuckets)
61 : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
62
63 Error visitKnownRecord(codeview::CVType &CVR,
64 codeview::UdtSourceLineRecord &Rec) override;
65 Error visitKnownRecord(codeview::CVType &CVR,
66 codeview::UdtModSourceLineRecord &Rec) override;
67 Error visitKnownRecord(codeview::CVType &CVR,
68 codeview::ClassRecord &Rec) override;
69 Error visitKnownRecord(codeview::CVType &CVR,
70 codeview::EnumRecord &Rec) override;
71 Error visitKnownRecord(codeview::CVType &CVR,
72 codeview::UnionRecord &Rec) override;
73 Error visitTypeBegin(codeview::CVType &CVR) override;
74
75 private:
76 Error verifySourceLine(codeview::TypeIndex TI);
77
78 Error errorInvalidHash() {
79 return make_error(
80 raw_error_code::invalid_tpi_hash,
81 "Type index is 0x" +
82 utohexstr(codeview::TypeIndex::FirstNonSimpleIndex + Index));
83 }
84
85 FixedStreamArray HashValues;
86 codeview::CVType RawRecord;
87 uint32_t NumHashBuckets;
88 uint32_t Index = -1;
89 };
18 Expected hashTypeRecord(const llvm::codeview::CVType &Type);
9019
9120 } // end namespace pdb
9221 } // end namespace llvm
1010
1111 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
1212 #include "llvm/DebugInfo/PDB/Native/Hash.h"
13 #include "llvm/DebugInfo/PDB/Native/RawError.h"
13 #include "llvm/Support/JamCRC.h"
1414
1515 using namespace llvm;
1616 using namespace llvm::codeview;
1717 using namespace llvm::pdb;
1818
1919 // Corresponds to `fUDTAnon`.
20 template static bool isAnonymous(T &Rec) {
21 StringRef Name = Rec.getName();
20 static bool isAnonymous(StringRef Name) {
2221 return Name == "" || Name == "__unnamed" ||
2322 Name.endswith("::") || Name.endswith("::__unnamed");
2423 }
2524
26 // Computes a hash for a given TPI record.
27 template
28 static uint32_t getTpiHash(T &Rec, ArrayRef FullRecord) {
29 auto Opts = static_cast(Rec.getOptions());
30
31 bool ForwardRef =
32 Opts & static_cast(ClassOptions::ForwardReference);
33 bool Scoped = Opts & static_cast(ClassOptions::Scoped);
34 bool UniqueName = Opts & static_cast(ClassOptions::HasUniqueName);
35 bool IsAnon = UniqueName && isAnonymous(Rec);
25 // Computes the hash for a user-defined type record. This could be a struct,
26 // class, union, or enum.
27 static uint32_t getHashForUdt(const TagRecord &Rec,
28 ArrayRef FullRecord) {
29 ClassOptions Opts = Rec.getOptions();
30 bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
31 bool Scoped = bool(Opts & ClassOptions::Scoped);
32 bool HasUniqueName = bool(Opts & ClassOptions::HasUniqueName);
33 bool IsAnon = HasUniqueName && isAnonymous(Rec.getName());
3634
3735 if (!ForwardRef && !Scoped && !IsAnon)
3836 return hashStringV1(Rec.getName());
39 if (!ForwardRef && UniqueName && !IsAnon)
37 if (!ForwardRef && HasUniqueName && !IsAnon)
4038 return hashStringV1(Rec.getUniqueName());
4139 return hashBufferV8(FullRecord);
4240 }
4341
44 template static uint32_t getSourceLineHash(T &Rec) {
42 template
43 static Expected getHashForUdt(const CVType &Rec) {
44 T Deserialized;
45 if (auto E = TypeDeserializer::deserializeAs(const_cast(Rec),
46 Deserialized))
47 return std::move(E);
48 return getHashForUdt(Deserialized, Rec.data());
49 }
50
51 template
52 static Expected getSourceLineHash(const CVType &Rec) {
53 T Deserialized;
54 if (auto E = TypeDeserializer::deserializeAs(const_cast(Rec),
55 Deserialized))
56 return std::move(E);
4557 char Buf[4];
46 support::endian::write32le(Buf, Rec.getUDT().getIndex());
58 support::endian::write32le(Buf, Deserialized.getUDT().getIndex());
4759 return hashStringV1(StringRef(Buf, 4));
4860 }
4961
50 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR,
51 UdtSourceLineRecord &Rec) {
52 CVR.Hash = getSourceLineHash(Rec);
62 Expected llvm::pdb::hashTypeRecord(const CVType &Rec) {
63 switch (Rec.kind()) {
64 case LF_CLASS:
65 case LF_STRUCTURE:
66 case LF_INTERFACE:
67 return getHashForUdt(Rec);
68 case LF_UNION:
69 return getHashForUdt(Rec);
70 case LF_ENUM:
71 return getHashForUdt(Rec);
72
73 case LF_UDT_SRC_LINE:
74 return getSourceLineHash(Rec);
75 case LF_UDT_MOD_SRC_LINE:
76 return getSourceLineHash(Rec);
77
78 default:
79 break;
80 }
81
82 // Run CRC32 over the bytes. This corresponds to `hashBufv8`.
83 JamCRC JC(/*Init=*/0U);
84 ArrayRef Bytes(reinterpret_cast(Rec.data().data()),
85 Rec.data().size());
86 JC.update(Bytes);
87 return JC.getCRC();
5388 }
54
55 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR,
56 UdtModSourceLineRecord &Rec) {
57 CVR.Hash = getSourceLineHash(Rec);
58 }
59
60 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, ClassRecord &Rec) {
61 CVR.Hash = getTpiHash(Rec, CVR.data());
62 }
63
64 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, EnumRecord &Rec) {
65 CVR.Hash = getTpiHash(Rec, CVR.data());
66 }
67
68 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, UnionRecord &Rec) {
69 CVR.Hash = getTpiHash(Rec, CVR.data());
70 }
71
72 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, UdtSourceLineRecord &Rec) {
73 return verifySourceLine(Rec.getUDT());
74 }
75
76 Error TpiHashVerifier::visitKnownRecord(CVType &CVR,
77 UdtModSourceLineRecord &Rec) {
78 return verifySourceLine(Rec.getUDT());
79 }
80
81 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, ClassRecord &Rec) {
82 if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index])
83 return errorInvalidHash();
84 return Error::success();
85 }
86 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, EnumRecord &Rec) {
87 if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index])
88 return errorInvalidHash();
89 return Error::success();
90 }
91 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, UnionRecord &Rec) {
92 if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index])
93 return errorInvalidHash();
94 return Error::success();
95 }
96
97 Error TpiHashVerifier::verifySourceLine(codeview::TypeIndex TI) {
98 char Buf[4];
99 support::endian::write32le(Buf, TI.getIndex());
100 uint32_t Hash = hashStringV1(StringRef(Buf, 4));
101 if (Hash % NumHashBuckets != HashValues[Index])
102 return errorInvalidHash();
103 return Error::success();
104 }
105
106 Error TpiHashVerifier::visitTypeBegin(CVType &Rec) {
107 ++Index;
108 RawRecord = Rec;
109 return Error::success();
110 }
9090 ALL: Types (TPI Stream)
9191 ALL-NEXT: ============================================================
9292 ALL-NEXT: Showing 75 records
93 ALL-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 205956]
94 ALL-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 163561]
93 ALL-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 0x32484]
94 ALL-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 0x27EE9]
9595 ALL-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1000
9696 ALL-NEXT: calling conv = cdecl, options = None
97 ALL-NEXT: 0x1002 | LF_FIELDLIST [size = 76, hash = 59811]
97 ALL-NEXT: 0x1002 | LF_FIELDLIST [size = 76, hash = 0xE9A3]
9898 ALL-NEXT: - LF_ENUMERATE [apartment = 1]
9999 ALL-NEXT: - LF_ENUMERATE [single = 2]
100100 ALL-NEXT: - LF_ENUMERATE [free = 3]
101101 ALL-NEXT: - LF_ENUMERATE [neutral = 4]
102102 ALL-NEXT: - LF_ENUMERATE [both = 5]
103 ALL-NEXT: 0x1003 | LF_ENUM [size = 120, hash = 208239] `__vc_attributes::threadingAttribute::threading_e`
103 ALL-NEXT: 0x1003 | LF_ENUM [size = 120, hash = 0x32D6F] `__vc_attributes::threadingAttribute::threading_e`
104104 ALL-NEXT: unique name: `.?AW4threading_e@threadingAttribute@__vc_attributes@@`
105105 ALL-NEXT: field list: 0x1002, underlying type: 0x0074 (int)
106106 ALL-NEXT: options: has unique name | is nested
107 ALL-NEXT: 0x1004 | LF_STRUCTURE [size = 100, hash = 16377] `__vc_attributes::threadingAttribute`
107 ALL-NEXT: 0x1004 | LF_STRUCTURE [size = 100, hash = 0x3FF9] `__vc_attributes::threadingAttribute`
108108 ALL-NEXT: unique name: `.?AUthreadingAttribute@__vc_attributes@@`
109109 ALL-NEXT: vtable: , base list: , field list:
110110 ALL-NEXT: options: forward ref | has unique name
111 ALL-NEXT: 0x1005 | LF_POINTER [size = 12, hash = 247078]
111 ALL-NEXT: 0x1005 | LF_POINTER [size = 12, hash = 0x3C526]
112112 ALL-NEXT: referent = 0x1004, mode = pointer, opts = const, kind = ptr32
113 ALL-NEXT: 0x1006 | LF_ARGLIST [size = 12, hash = 194342]
113 ALL-NEXT: 0x1006 | LF_ARGLIST [size = 12, hash = 0x2F726]
114114 ALL-NEXT: 0x1003: `__vc_attributes::threadingAttribute::threading_e`
115 ALL-NEXT: 0x1007 | LF_MFUNCTION [size = 28, hash = 254156]
115 ALL-NEXT: 0x1007 | LF_MFUNCTION [size = 28, hash = 0x3E0CC]
116116 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1006
117117 ALL-NEXT: class type = 0x1004, this type = 0x1005, this adjust = 0
118118 ALL-NEXT: calling conv = thiscall, options = constructor
119 ALL-NEXT: 0x1008 | LF_MFUNCTION [size = 28, hash = 194536]
119 ALL-NEXT: 0x1008 | LF_MFUNCTION [size = 28, hash = 0x2F7E8]
120120 ALL-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x1000
121121 ALL-NEXT: class type = 0x1004, this type = 0x1005, this adjust = 0
122122 ALL-NEXT: calling conv = thiscall, options = constructor
123 ALL-NEXT: 0x1009 | LF_METHODLIST [size = 20, hash = 167492]
123 ALL-NEXT: 0x1009 | LF_METHODLIST [size = 20, hash = 0x28E44]
124124 ALL-NEXT: - Method [type = 0x1007, vftable offset = -1, attrs = public]
125125 ALL-NEXT: - Method [type = 0x1008, vftable offset = -1, attrs = public]
126 ALL-NEXT: 0x100A | LF_FIELDLIST [size = 68, hash = 185421]
126 ALL-NEXT: 0x100A | LF_FIELDLIST [size = 68, hash = 0x2D44D]
127127 ALL-NEXT: - LF_NESTTYPE [name = `threading_e`, parent = 0x1003]
128128 ALL-NEXT: - LF_METHOD [name = `threadingAttribute`, # overloads = 2, overload list = 0x1009]
129129 ALL-NEXT: - LF_MEMBER [name = `value`, Type = 0x1003, offset = 0, attrs = public]
130 ALL-NEXT: 0x100B | LF_STRUCTURE [size = 100, hash = 119540] `__vc_attributes::threadingAttribute`
130 ALL-NEXT: 0x100B | LF_STRUCTURE [size = 100, hash = 0x1D2F4] `__vc_attributes::threadingAttribute`
131131 ALL-NEXT: unique name: `.?AUthreadingAttribute@__vc_attributes@@`
132132 ALL-NEXT: vtable: , base list: , field list: 0x100A
133133 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
134 ALL-NEXT: 0x100C | LF_FIELDLIST [size = 48, hash = 261871]
134 ALL-NEXT: 0x100C | LF_FIELDLIST [size = 48, hash = 0x3FEEF]
135135 ALL-NEXT: - LF_ENUMERATE [native = 0]
136136 ALL-NEXT: - LF_ENUMERATE [com = 1]
137137 ALL-NEXT: - LF_ENUMERATE [managed = 2]
138 ALL-NEXT: 0x100D | LF_ENUM [size = 120, hash = 198119] `__vc_attributes::event_receiverAttribute::type_e`
138 ALL-NEXT: 0x100D | LF_ENUM [size = 120, hash = 0x305E7] `__vc_attributes::event_receiverAttribute::type_e`
139139 ALL-NEXT: unique name: `.?AW4type_e@event_receiverAttribute@__vc_attributes@@`
140140 ALL-NEXT: field list: 0x100C, underlying type: 0x0074 (int)
141141 ALL-NEXT: options: has unique name | is nested
142 ALL-NEXT: 0x100E | LF_STRUCTURE [size = 112, hash = 48056] `__vc_attributes::event_receiverAttribute`
142 ALL-NEXT: 0x100E | LF_STRUCTURE [size = 112, hash = 0xBBB8] `__vc_attributes::event_receiverAttribute`
143143 ALL-NEXT: unique name: `.?AUevent_receiverAttribute@__vc_attributes@@`
144144 ALL-NEXT: vtable: , base list: , field list:
145145 ALL-NEXT: options: forward ref | has unique name
146 ALL-NEXT: 0x100F | LF_POINTER [size = 12, hash = 251486]
146 ALL-NEXT: 0x100F | LF_POINTER [size = 12, hash = 0x3D65E]
147147 ALL-NEXT: referent = 0x100E, mode = pointer, opts = const, kind = ptr32
148 ALL-NEXT: 0x1010 | LF_ARGLIST [size = 16, hash = 134580]
148 ALL-NEXT: 0x1010 | LF_ARGLIST [size = 16, hash = 0x20DB4]
149149 ALL-NEXT: 0x100D: `__vc_attributes::event_receiverAttribute::type_e`
150150 ALL-NEXT: 0x0030 (bool): `bool`
151 ALL-NEXT: 0x1011 | LF_MFUNCTION [size = 28, hash = 148190]
151 ALL-NEXT: 0x1011 | LF_MFUNCTION [size = 28, hash = 0x242DE]
152152 ALL-NEXT: return type = 0x0003 (void), # args = 2, param list = 0x1010
153153 ALL-NEXT: class type = 0x100E, this type = 0x100F, this adjust = 0
154154 ALL-NEXT: calling conv = thiscall, options = constructor
155 ALL-NEXT: 0x1012 | LF_ARGLIST [size = 12, hash = 113636]
155 ALL-NEXT: 0x1012 | LF_ARGLIST [size = 12, hash = 0x1BBE4]
156156 ALL-NEXT: 0x100D: `__vc_attributes::event_receiverAttribute::type_e`
157 ALL-NEXT: 0x1013 | LF_MFUNCTION [size = 28, hash = 53336]
157 ALL-NEXT: 0x1013 | LF_MFUNCTION [size = 28, hash = 0xD058]
158158 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1012
159159 ALL-NEXT: class type = 0x100E, this type = 0x100F, this adjust = 0
160160 ALL-NEXT: calling conv = thiscall, options = constructor
161 ALL-NEXT: 0x1014 | LF_MFUNCTION [size = 28, hash = 55779]
161 ALL-NEXT: 0x1014 | LF_MFUNCTION [size = 28, hash = 0xD9E3]
162162 ALL-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x1000
163163 ALL-NEXT: class type = 0x100E, this type = 0x100F, this adjust = 0
164164 ALL-NEXT: calling conv = thiscall, options = constructor
165 ALL-NEXT: 0x1015 | LF_METHODLIST [size = 28, hash = 220695]
165 ALL-NEXT: 0x1015 | LF_METHODLIST [size = 28, hash = 0x35E17]
166166 ALL-NEXT: - Method [type = 0x1011, vftable offset = -1, attrs = public]
167167 ALL-NEXT: - Method [type = 0x1013, vftable offset = -1, attrs = public]
168168 ALL-NEXT: - Method [type = 0x1014, vftable offset = -1, attrs = public]
169 ALL-NEXT: 0x1016 | LF_FIELDLIST [size = 96, hash = 198114]
169 ALL-NEXT: 0x1016 | LF_FIELDLIST [size = 96, hash = 0x305E2]
170170 ALL-NEXT: - LF_NESTTYPE [name = `type_e`, parent = 0x100D]
171171 ALL-NEXT: - LF_METHOD [name = `event_receiverAttribute`, # overloads = 3, overload list = 0x1015]
172172 ALL-NEXT: - LF_MEMBER [name = `type`, Type = 0x100D, offset = 0, attrs = public]
173173 ALL-NEXT: - LF_MEMBER [name = `layout_dependent`, Type = 0x0030 (bool), offset = 4, attrs = public]
174 ALL-NEXT: 0x1017 | LF_STRUCTURE [size = 112, hash = 148734] `__vc_attributes::event_receiverAttribute`
174 ALL-NEXT: 0x1017 | LF_STRUCTURE [size = 112, hash = 0x244FE] `__vc_attributes::event_receiverAttribute`
175175 ALL-NEXT: unique name: `.?AUevent_receiverAttribute@__vc_attributes@@`
176176 ALL-NEXT: vtable: , base list: , field list: 0x1016
177177 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
178 ALL-NEXT: 0x1018 | LF_FIELDLIST [size = 48, hash = 81128]
178 ALL-NEXT: 0x1018 | LF_FIELDLIST [size = 48, hash = 0x13CE8]
179179 ALL-NEXT: - LF_ENUMERATE [never = 0]
180180 ALL-NEXT: - LF_ENUMERATE [allowed = 1]
181181 ALL-NEXT: - LF_ENUMERATE [always = 2]
182 ALL-NEXT: 0x1019 | LF_ENUM [size = 116, hash = 60158] `__vc_attributes::aggregatableAttribute::type_e`
182 ALL-NEXT: 0x1019 | LF_ENUM [size = 116, hash = 0xEAFE] `__vc_attributes::aggregatableAttribute::type_e`
183183 ALL-NEXT: unique name: `.?AW4type_e@aggregatableAttribute@__vc_attributes@@`
184184 ALL-NEXT: field list: 0x1018, underlying type: 0x0074 (int)
185185 ALL-NEXT: options: has unique name | is nested
186 ALL-NEXT: 0x101A | LF_STRUCTURE [size = 108, hash = 217249] `__vc_attributes::aggregatableAttribute`
186 ALL-NEXT: 0x101A | LF_STRUCTURE [size = 108, hash = 0x350A1] `__vc_attributes::aggregatableAttribute`
187187 ALL-NEXT: unique name: `.?AUaggregatableAttribute@__vc_attributes@@`
188188 ALL-NEXT: vtable: , base list: , field list:
189189 ALL-NEXT: options: forward ref | has unique name
190 ALL-NEXT: 0x101B | LF_POINTER [size = 12, hash = 174209]
190 ALL-NEXT: 0x101B | LF_POINTER [size = 12, hash = 0x2A881]
191191 ALL-NEXT: referent = 0x101A, mode = pointer, opts = const, kind = ptr32
192 ALL-NEXT: 0x101C | LF_ARGLIST [size = 12, hash = 159978]
192 ALL-NEXT: 0x101C | LF_ARGLIST [size = 12, hash = 0x270EA]
193193 ALL-NEXT: 0x1019: `__vc_attributes::aggregatableAttribute::type_e`
194 ALL-NEXT: 0x101D | LF_MFUNCTION [size = 28, hash = 249504]
194 ALL-NEXT: 0x101D | LF_MFUNCTION [size = 28, hash = 0x3CEA0]
195195 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x101C
196196 ALL-NEXT: class type = 0x101A, this type = 0x101B, this adjust = 0
197197 ALL-NEXT: calling conv = thiscall, options = constructor
198 ALL-NEXT: 0x101E | LF_MFUNCTION [size = 28, hash = 141941]
198 ALL-NEXT: 0x101E | LF_MFUNCTION [size = 28, hash = 0x22A75]
199199 ALL-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x1000
200200 ALL-NEXT: class type = 0x101A, this type = 0x101B, this adjust = 0
201201 ALL-NEXT: calling conv = thiscall, options = constructor
202 ALL-NEXT: 0x101F | LF_METHODLIST [size = 20, hash = 238785]
202 ALL-NEXT: 0x101F | LF_METHODLIST [size = 20, hash = 0x3A4C1]
203203 ALL-NEXT: - Method [type = 0x101D, vftable offset = -1, attrs = public]
204204 ALL-NEXT: - Method [type = 0x101E, vftable offset = -1, attrs = public]
205 ALL-NEXT: 0x1020 | LF_FIELDLIST [size = 68, hash = 6214]
205 ALL-NEXT: 0x1020 | LF_FIELDLIST [size = 68, hash = 0x1846]
206206 ALL-NEXT: - LF_NESTTYPE [name = `type_e`, parent = 0x1019]
207207 ALL-NEXT: - LF_METHOD [name = `aggregatableAttribute`, # overloads = 2, overload list = 0x101F]
208208 ALL-NEXT: - LF_MEMBER [name = `type`, Type = 0x1019, offset = 0, attrs = public]
209 ALL-NEXT: 0x1021 | LF_STRUCTURE [size = 108, hash = 94935] `__vc_attributes::aggregatableAttribute`
209 ALL-NEXT: 0x1021 | LF_STRUCTURE [size = 108, hash = 0x172D7] `__vc_attributes::aggregatableAttribute`
210210 ALL-NEXT: unique name: `.?AUaggregatableAttribute@__vc_attributes@@`
211211 ALL-NEXT: vtable: , base list: , field list: 0x1020
212212 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
213 ALL-NEXT: 0x1022 | LF_ENUM [size = 116, hash = 151449] `__vc_attributes::event_sourceAttribute::type_e`
213 ALL-NEXT: 0x1022 | LF_ENUM [size = 116, hash = 0x24F99] `__vc_attributes::event_sourceAttribute::type_e`
214214 ALL-NEXT: unique name: `.?AW4type_e@event_sourceAttribute@__vc_attributes@@`
215215 ALL-NEXT: field list: 0x100C, underlying type: 0x0074 (int)
216216 ALL-NEXT: options: has unique name | is nested
217 ALL-NEXT: 0x1023 | LF_FIELDLIST [size = 28, hash = 135589]
217 ALL-NEXT: 0x1023 | LF_FIELDLIST [size = 28, hash = 0x211A5]
218218 ALL-NEXT: - LF_ENUMERATE [speed = 0]
219219 ALL-NEXT: - LF_ENUMERATE [size = 1]
220 ALL-NEXT: 0x1024 | LF_ENUM [size = 124, hash = 73373] `__vc_attributes::event_sourceAttribute::optimize_e`
220 ALL-NEXT: 0x1024 | LF_ENUM [size = 124, hash = 0x11E9D] `__vc_attributes::event_sourceAttribute::optimize_e`
221221 ALL-NEXT: unique name: `.?AW4optimize_e@event_sourceAttribute@__vc_attributes@@`
222222 ALL-NEXT: field list: 0x1023, underlying type: 0x0074 (int)
223223 ALL-NEXT: options: has unique name | is nested
224 ALL-NEXT: 0x1025 | LF_STRUCTURE [size = 108, hash = 96512] `__vc_attributes::event_sourceAttribute`
224 ALL-NEXT: 0x1025 | LF_STRUCTURE [size = 108, hash = 0x17900] `__vc_attributes::event_sourceAttribute`
225225 ALL-NEXT: unique name: `.?AUevent_sourceAttribute@__vc_attributes@@`
226226 ALL-NEXT: vtable: , base list: , field list:
227227 ALL-NEXT: options: forward ref | has unique name
228 ALL-NEXT: 0x1026 | LF_POINTER [size = 12, hash = 254299]
228 ALL-NEXT: 0x1026 | LF_POINTER [size = 12, hash = 0x3E15B]
229229 ALL-NEXT: referent = 0x1025, mode = pointer, opts = const, kind = ptr32
230 ALL-NEXT: 0x1027 | LF_ARGLIST [size = 12, hash = 17744]
230 ALL-NEXT: 0x1027 | LF_ARGLIST [size = 12, hash = 0x4550]
231231 ALL-NEXT: 0x1022: `__vc_attributes::event_sourceAttribute::type_e`
232 ALL-NEXT: 0x1028 | LF_MFUNCTION [size = 28, hash = 239514]
232 ALL-NEXT: 0x1028 | LF_MFUNCTION [size = 28, hash = 0x3A79A]
233233 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1027
234234 ALL-NEXT: class type = 0x1025, this type = 0x1026, this adjust = 0
235235 ALL-NEXT: calling conv = thiscall, options = constructor
236 ALL-NEXT: 0x1029 | LF_MFUNCTION [size = 28, hash = 173189]
236 ALL-NEXT: 0x1029 | LF_MFUNCTION [size = 28, hash = 0x2A485]
237237 ALL-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x1000
238238 ALL-NEXT: class type = 0x1025, this type = 0x1026, this adjust = 0
239239 ALL-NEXT: calling conv = thiscall, options = constructor
240 ALL-NEXT: 0x102A | LF_METHODLIST [size = 20, hash = 130544]
240 ALL-NEXT: 0x102A | LF_METHODLIST [size = 20, hash = 0x1FDF0]
241241 ALL-NEXT: - Method [type = 0x1028, vftable offset = -1, attrs = public]
242242 ALL-NEXT: - Method [type = 0x1029, vftable offset = -1, attrs = public]
243 ALL-NEXT: 0x102B | LF_FIELDLIST [size = 128, hash = 204437]
243 ALL-NEXT: 0x102B | LF_FIELDLIST [size = 128, hash = 0x31E95]
244244 ALL-NEXT: - LF_NESTTYPE [name = `type_e`, parent = 0x1022]
245245 ALL-NEXT: - LF_NESTTYPE [name = `optimize_e`, parent = 0x1024]
246246 ALL-NEXT: - LF_METHOD [name = `event_sourceAttribute`, # overloads = 2, overload list = 0x102A]
247247 ALL-NEXT: - LF_MEMBER [name = `type`, Type = 0x1022, offset = 0, attrs = public]
248248 ALL-NEXT: - LF_MEMBER [name = `optimize`, Type = 0x1024, offset = 4, attrs = public]
249249 ALL-NEXT: - LF_MEMBER [name = `decorate`, Type = 0x0030 (bool), offset = 8, attrs = public]
250 ALL-NEXT: 0x102C | LF_STRUCTURE [size = 108, hash = 238560] `__vc_attributes::event_sourceAttribute`
250 ALL-NEXT: 0x102C | LF_STRUCTURE [size = 108, hash = 0x3A3E0] `__vc_attributes::event_sourceAttribute`
251251 ALL-NEXT: unique name: `.?AUevent_sourceAttribute@__vc_attributes@@`
252252 ALL-NEXT: vtable: , base list: , field list: 0x102B
253253 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
254 ALL-NEXT: 0x102D | LF_FIELDLIST [size = 92, hash = 144673]
254 ALL-NEXT: 0x102D | LF_FIELDLIST [size = 92, hash = 0x23521]
255255 ALL-NEXT: - LF_ENUMERATE [dll = 1]
256256 ALL-NEXT: - LF_ENUMERATE [exe = 2]
257257 ALL-NEXT: - LF_ENUMERATE [service = 3]
258258 ALL-NEXT: - LF_ENUMERATE [unspecified = 4]
259259 ALL-NEXT: - LF_ENUMERATE [EXE = 2]
260260 ALL-NEXT: - LF_ENUMERATE [SERVICE = 3]
261 ALL-NEXT: 0x102E | LF_ENUM [size = 104, hash = 115151] `__vc_attributes::moduleAttribute::type_e`
261 ALL-NEXT: 0x102E | LF_ENUM [size = 104, hash = 0x1C1CF] `__vc_attributes::moduleAttribute::type_e`
262262 ALL-NEXT: unique name: `.?AW4type_e@moduleAttribute@__vc_attributes@@`
263263 ALL-NEXT: field list: 0x102D, underlying type: 0x0074 (int)
264264 ALL-NEXT: options: has unique name | is nested
265 ALL-NEXT: 0x102F | LF_STRUCTURE [size = 96, hash = 197306] `__vc_attributes::moduleAttribute`
265 ALL-NEXT: 0x102F | LF_STRUCTURE [size = 96, hash = 0x302BA] `__vc_attributes::moduleAttribute`
266266 ALL-NEXT: unique name: `.?AUmoduleAttribute@__vc_attributes@@`
267267 ALL-NEXT: vtable: , base list: , field list:
268268 ALL-NEXT: options: forward ref | has unique name
269 ALL-NEXT: 0x1030 | LF_POINTER [size = 12, hash = 256035]
269 ALL-NEXT: 0x1030 | LF_POINTER [size = 12, hash = 0x3E823]
270270 ALL-NEXT: referent = 0x102F, mode = pointer, opts = const, kind = ptr32
271 ALL-NEXT: 0x1031 | LF_MODIFIER [size = 12, hash = 101096]
271 ALL-NEXT: 0x1031 | LF_MODIFIER [size = 12, hash = 0x18AE8]
272272 ALL-NEXT: referent = 0x0070 (char), modifiers = const
273 ALL-NEXT: 0x1032 | LF_POINTER [size = 12, hash = 231280]
273 ALL-NEXT: 0x1032 | LF_POINTER [size = 12, hash = 0x38770]
274274 ALL-NEXT: referent = 0x1031, mode = pointer, opts = None, kind = ptr32
275 ALL-NEXT: 0x1033 | LF_ARGLIST [size = 68, hash = 52156]
275 ALL-NEXT: 0x1033 | LF_ARGLIST [size = 68, hash = 0xCBBC]
276276 ALL-NEXT: 0x102E: `__vc_attributes::moduleAttribute::type_e`
277277 ALL-NEXT: 0x1032: `const char*`
278278 ALL-NEXT: 0x1032: `const char*`
288288 ALL-NEXT: 0x0030 (bool): `bool`
289289 ALL-NEXT: 0x1032: `const char*`
290290 ALL-NEXT: 0x1032: `const char*`
291 ALL-NEXT: 0x1034 | LF_MFUNCTION [size = 28, hash = 48854]
291 ALL-NEXT: 0x1034 | LF_MFUNCTION [size = 28, hash = 0xBED6]
292292 ALL-NEXT: return type = 0x0003 (void), # args = 15, param list = 0x1033
293293 ALL-NEXT: class type = 0x102F, this type = 0x1030, this adjust = 0
294294 ALL-NEXT: calling conv = thiscall, options = constructor
295 ALL-NEXT: 0x1035 | LF_ARGLIST [size = 12, hash = 170035]
295 ALL-NEXT: 0x1035 | LF_ARGLIST [size = 12, hash = 0x29833]
296296 ALL-NEXT: 0x102E: `__vc_attributes::moduleAttribute::type_e`
297 ALL-NEXT: 0x1036 | LF_MFUNCTION [size = 28, hash = 177041]
297 ALL-NEXT: 0x1036 | LF_MFUNCTION [size = 28, hash = 0x2B391]
298298 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1035
299299 ALL-NEXT: class type = 0x102F, this type = 0x1030, this adjust = 0
300300 ALL-NEXT: calling conv = thiscall, options = constructor
301 ALL-NEXT: 0x1037 | LF_MFUNCTION [size = 28, hash = 102745]
301 ALL-NEXT: 0x1037 | LF_MFUNCTION [size = 28, hash = 0x19159]
302302 ALL-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x1000
303303 ALL-NEXT: class type = 0x102F, this type = 0x1030, this adjust = 0
304304 ALL-NEXT: calling conv = thiscall, options = constructor
305 ALL-NEXT: 0x1038 | LF_METHODLIST [size = 28, hash = 16947]
305 ALL-NEXT: 0x1038 | LF_METHODLIST [size = 28, hash = 0x4233]
306306 ALL-NEXT: - Method [type = 0x1034, vftable offset = -1, attrs = public]
307307 ALL-NEXT: - Method [type = 0x1036, vftable offset = -1, attrs = public]
308308 ALL-NEXT: - Method [type = 0x1037, vftable offset = -1, attrs = public]
309 ALL-NEXT: 0x1039 | LF_FIELDLIST [size = 356, hash = 183703]
309 ALL-NEXT: 0x1039 | LF_FIELDLIST [size = 356, hash = 0x2CD97]
310310 ALL-NEXT: - LF_NESTTYPE [name = `type_e`, parent = 0x102E]
311311 ALL-NEXT: - LF_METHOD [name = `moduleAttribute`, # overloads = 3, overload list = 0x1038]
312312 ALL-NEXT: - LF_MEMBER [name = `type`, Type = 0x102E, offset = 0, attrs = public]
324324 ALL-NEXT: - LF_MEMBER [name = `restricted`, Type = 0x0030 (bool), offset = 45, attrs = public]
325325 ALL-NEXT: - LF_MEMBER [name = `custom`, Type = 0x1032, offset = 48, attrs = public]
326326 ALL-NEXT: - LF_MEMBER [name = `resource_name`, Type = 0x1032, offset = 52, attrs = public]
327 ALL-NEXT: 0x103A | LF_STRUCTURE [size = 96, hash = 98548] `__vc_attributes::moduleAttribute`
327 ALL-NEXT: 0x103A | LF_STRUCTURE [size = 96, hash = 0x180F4] `__vc_attributes::moduleAttribute`
328328 ALL-NEXT: unique name: `.?AUmoduleAttribute@__vc_attributes@@`
329329 ALL-NEXT: vtable: , base list: , field list: 0x1039
330330 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
331 ALL-NEXT: 0x103B | LF_FIELDLIST [size = 756, hash = 35693]
331 ALL-NEXT: 0x103B | LF_FIELDLIST [size = 756, hash = 0x8B6D]
332332 ALL-NEXT: - LF_ENUMERATE [eAnyUsage = 0]
333333 ALL-NEXT: - LF_ENUMERATE [eCoClassUsage = 1]
334334 ALL-NEXT: - LF_ENUMERATE [eCOMInterfaceUsage = 2]
359359 ALL-NEXT: - LF_ENUMERATE [eIllegalUsage = 33554432]
360360 ALL-NEXT: - LF_ENUMERATE [eAsynchronousUsage = 67108864]
361361 ALL-NEXT: - LF_ENUMERATE [eAnyIDLUsage = 4161535]
362 ALL-NEXT: 0x103C | LF_ENUM [size = 140, hash = 171328] `__vc_attributes::helper_attributes::usageAttribute::usage_e`
362 ALL-NEXT: 0x103C | LF_ENUM [size = 140, hash = 0x29D40] `__vc_attributes::helper_attributes::usageAttribute::usage_e`
363363 ALL-NEXT: unique name: `.?AW4usage_e@usageAttribute@helper_attributes@__vc_attributes@@`
364364 ALL-NEXT: field list: 0x103B, underlying type: 0x0074 (int)
365365 ALL-NEXT: options: has unique name | is nested
366 ALL-NEXT: 0x103D | LF_STRUCTURE [size = 128, hash = 203640] `__vc_attributes::helper_attributes::usageAttribute`
366 ALL-NEXT: 0x103D | LF_STRUCTURE [size = 128, hash = 0x31B78] `__vc_attributes::helper_attributes::usageAttribute`
367367 ALL-NEXT: unique name: `.?AUusageAttribute@helper_attributes@__vc_attributes@@`
368368 ALL-NEXT: vtable: , base list: , field list:
369369 ALL-NEXT: options: forward ref | has unique name
370 ALL-NEXT: 0x103E | LF_POINTER [size = 12, hash = 139292]
370 ALL-NEXT: 0x103E | LF_POINTER [size = 12, hash = 0x2201C]
371371 ALL-NEXT: referent = 0x103D, mode = pointer, opts = const, kind = ptr32
372 ALL-NEXT: 0x103F | LF_ARGLIST [size = 12, hash = 49018]
372 ALL-NEXT: 0x103F | LF_ARGLIST [size = 12, hash = 0xBF7A]
373373 ALL-NEXT: 0x0075 (unsigned): `unsigned`
374 ALL-NEXT: 0x1040 | LF_MFUNCTION [size = 28, hash = 43821]
374 ALL-NEXT: 0x1040 | LF_MFUNCTION [size = 28, hash = 0xAB2D]
375375 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x103F
376376 ALL-NEXT: class type = 0x103D, this type = 0x103E, this adjust = 0
377377 ALL-NEXT: calling conv = thiscall, options = constructor
378 ALL-NEXT: 0x1041 | LF_FIELDLIST [size = 60, hash = 202555]
378 ALL-NEXT: 0x1041 | LF_FIELDLIST [size = 60, hash = 0x3173B]
379379 ALL-NEXT: - LF_NESTTYPE [name = `usage_e`, parent = 0x103C]
380380 ALL-NEXT: - LF_ONEMETHOD [name = `usageAttribute`]
381381 ALL-NEXT: type = 0x1040, vftable offset = -1, attrs = public
382382 ALL-NEXT: - LF_MEMBER [name = `value`, Type = 0x0075 (unsigned), offset = 0, attrs = public]
383 ALL-NEXT: 0x1042 | LF_STRUCTURE [size = 128, hash = 165040] `__vc_attributes::helper_attributes::usageAttribute`
383 ALL-NEXT: 0x1042 | LF_STRUCTURE [size = 128, hash = 0x284B0] `__vc_attributes::helper_attributes::usageAttribute`
384384 ALL-NEXT: unique name: `.?AUusageAttribute@helper_attributes@__vc_attributes@@`
385385 ALL-NEXT: vtable: , base list: , field list: 0x1041
386386 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
387 ALL-NEXT: 0x1043 | LF_FIELDLIST [size = 68, hash = 215835]
387 ALL-NEXT: 0x1043 | LF_FIELDLIST [size = 68, hash = 0x34B1B]
388388 ALL-NEXT: - LF_ENUMERATE [eBoolean = 0]
389389 ALL-NEXT: - LF_ENUMERATE [eInteger = 1]
390390 ALL-NEXT: - LF_ENUMERATE [eFloat = 2]
391391 ALL-NEXT: - LF_ENUMERATE [eDouble = 3]
392 ALL-NEXT: 0x1044 | LF_ENUM [size = 148, hash = 142625] `__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e`
392 ALL-NEXT: 0x1044 | LF_ENUM [size = 148, hash = 0x22D21] `__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e`
393393 ALL-NEXT: unique name: `.?AW4type_e@v1_alttypeAttribute@helper_attributes@__vc_attributes@@`
394394 ALL-NEXT: field list: 0x1043, underlying type: 0x0074 (int)
395395 ALL-NEXT: options: has unique name | is nested
396 ALL-NEXT: 0x1045 | LF_STRUCTURE [size = 140, hash = 52534] `__vc_attributes::helper_attributes::v1_alttypeAttribute`
396 ALL-NEXT: 0x1045 | LF_STRUCTURE [size = 140, hash = 0xCD36] `__vc_attributes::helper_attributes::v1_alttypeAttribute`
397397 ALL-NEXT: unique name: `.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@`
398398 ALL-NEXT: vtable: , base list: , field list:
399399 ALL-NEXT: options: forward ref | has unique name
400 ALL-NEXT: 0x1046 | LF_POINTER [size = 12, hash = 44186]
400 ALL-NEXT: 0x1046 | LF_POINTER [size = 12, hash = 0xAC9A]
401401 ALL-NEXT: referent = 0x1045, mode = pointer, opts = const, kind = ptr32
402 ALL-NEXT: 0x1047 | LF_ARGLIST [size = 12, hash = 103930]
402 ALL-NEXT: 0x1047 | LF_ARGLIST [size = 12, hash = 0x195FA]
403403 ALL-NEXT: 0x1044: `__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e`
404 ALL-NEXT: 0x1048 | LF_MFUNCTION [size = 28, hash = 110942]
404 ALL-NEXT: 0x1048 | LF_MFUNCTION [size = 28, hash = 0x1B15E]
405405 ALL-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1047
406406 ALL-NEXT: class type = 0x1045, this type = 0x1046, this adjust = 0
407407 ALL-NEXT: calling conv = thiscall, options = constructor
408 ALL-NEXT: 0x1049 | LF_FIELDLIST [size = 64, hash = 17991]
408 ALL-NEXT: 0x1049 | LF_FIELDLIST [size = 64, hash = 0x4647]
409409 ALL-NEXT: - LF_NESTTYPE [name = `type_e`, parent = 0x1044]
410410 ALL-NEXT: - LF_ONEMETHOD [name = `v1_alttypeAttribute`]
411411 ALL-NEXT: type = 0x1048, vftable offset = -1, attrs = public
412412 ALL-NEXT: - LF_MEMBER [name = `type`, Type = 0x1044, offset = 0, attrs = public]
413 ALL-NEXT: 0x104A | LF_STRUCTURE [size = 140, hash = 213215] `__vc_attributes::helper_attributes::v1_alttypeAttribute`
413 ALL-NEXT: 0x104A | LF_STRUCTURE [size = 140, hash = 0x340DF] `__vc_attributes::helper_attributes::v1_alttypeAttribute`
414414 ALL-NEXT: unique name: `.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@`
415415 ALL-NEXT: vtable: , base list: , field list: 0x1049
416416 ALL-NEXT: options: has ctor / dtor | contains nested class | has unique name
653653 NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
654654
655655 MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
656 Stream.getHashValues());
656 Stream.getNumHashBuckets(), Stream.getHashValues());
657657
658658 if (auto EC = codeview::visitTypeStream(Types, V)) {
659659 Printer.formatLine("An error occurred dumping type records: {0}",
669669 NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
670670
671671 MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
672 Stream.getHashValues());
672 Stream.getNumHashBuckets(), Stream.getHashValues());
673673
674674 if (opts::dump::DumpTypeDependents) {
675675 // If we need to dump all dependents, then iterate each index and find
1717 #include "llvm/DebugInfo/CodeView/Formatters.h"
1818 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
1919 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
20 #include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
2021 #include "llvm/Support/FormatVariadic.h"
2122 #include "llvm/Support/MathExtras.h"
2223
213214 getLeafTypeName(Record.Type), Record.length());
214215 } else {
215216 std::string H;
216 if (Index.toArrayIndex() >= HashValues.size())
217 if (Index.toArrayIndex() >= HashValues.size()) {
217218 H = "(not present)";
218 else
219 H = utostr(HashValues[Index.toArrayIndex()]);
219 } else {
220 uint32_t Hash = HashValues[Index.toArrayIndex()];
221 Expected MaybeHash = hashTypeRecord(Record);
222 if (!MaybeHash)
223 return MaybeHash.takeError();
224 uint32_t OurHash = *MaybeHash;
225 OurHash %= NumHashBuckets;
226 if (Hash == OurHash)
227 H = "0x" + utohexstr(Hash);
228 else
229 H = "0x" + utohexstr(Hash) + ", our hash = 0x" + utohexstr(OurHash);
230 }
220231 P.formatLine("{0} | {1} [size = {2}, hash = {3}]",
221232 fmt_align(Index, AlignStyle::Right, Width),
222233 getLeafTypeName(Record.Type), Record.length(), H);
2424 public:
2525 MinimalTypeDumpVisitor(LinePrinter &P, uint32_t Width, bool RecordBytes,
2626 bool Hashes, codeview::LazyRandomTypeCollection &Types,
27 uint32_t NumHashBuckets,
2728 FixedStreamArray HashValues)
2829 : P(P), Width(Width), RecordBytes(RecordBytes), Hashes(Hashes),
29 Types(Types), HashValues(HashValues) {}
30 Types(Types), NumHashBuckets(NumHashBuckets), HashValues(HashValues) {}
3031
3132 Error visitTypeBegin(codeview::CVType &Record,
3233 codeview::TypeIndex Index) override;
5253 bool RecordBytes = false;
5354 bool Hashes = false;
5455 codeview::LazyRandomTypeCollection &Types;
56 uint32_t NumHashBuckets;
5557 FixedStreamArray HashValues;
5658 };
5759 } // namespace pdb