Index: lib/DebugInfo/PDB/Raw/TpiStream.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -65,22 +65,20 @@ TpiStream::~TpiStream() {} // Computes a hash for a given TPI record. -template static uint32_t getTpiHash(T &Rec) { +template +static uint32_t getTpiHash(T &Rec, const CVRecord &RawRec) { auto Opts = static_cast(Rec.getOptions()); - // We don't know how to calculate a hash value for this yet. - // Currently we just skip it. - if (Opts & static_cast(ClassOptions::ForwardReference)) - return 0; + bool ForwardRef = + Opts & static_cast(ClassOptions::ForwardReference); + bool Scoped = Opts & static_cast(ClassOptions::Scoped); + bool UniqueName = Opts & static_cast(ClassOptions::HasUniqueName); - if (!(Opts & static_cast(ClassOptions::Scoped))) + if (!ForwardRef && !Scoped) return hashStringV1(Rec.getName()); - - if (Opts & static_cast(ClassOptions::HasUniqueName)) + if (!ForwardRef && UniqueName) return hashStringV1(Rec.getUniqueName()); - - // This case is not implemented yet. - return 0; + return hashBufferV8(RawRec.RawData); } namespace { @@ -102,12 +100,14 @@ void visitStruct(ClassRecord &Rec) { verify(Rec); } void visitUnion(UnionRecord &Rec) { verify(Rec); } + void visitTypeBegin(const CVRecord &Rec) { RawRecord = &Rec; } + void visitTypeEnd(const CVRecord &Record) { ++Index; } private: template void verify(T &Rec) { - uint32_t Hash = getTpiHash(Rec); - if (Hash && Hash % NumHashBuckets != HashValues[Index]) + uint32_t Hash = getTpiHash(Rec, *RawRecord); + if (Hash % NumHashBuckets != HashValues[Index]) parseError(); } @@ -120,6 +120,7 @@ } FixedStreamArray HashValues; + const CVRecord *RawRecord; uint32_t NumHashBuckets; uint32_t Index = 0; };