From 1f6372c429ce6b85a572c213d53f0ed8d293ff38 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 16 Jun 2016 18:00:28 +0000 Subject: [pdb] Change type visitor pattern to be dynamic. This allows better catching of compiler errors since we can use the override keyword to verify that methods are actually overridden. Also in this patch I've changed from storing a boolean Error code everywhere to returning an llvm::Error, to propagate richer error information up the call stack. Reviewed By: ruiu, rnk Differential Revision: http://reviews.llvm.org/D21410 llvm-svn: 272926 --- llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | 40 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp') diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp index 99e5037ad63..46717f23a63 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -84,39 +84,44 @@ template static uint32_t getTpiHash(T &Rec) { } namespace { -class TpiHashVerifier : public CVTypeVisitor { +class TpiHashVerifier : public TypeVisitorCallbacks { public: TpiHashVerifier(FixedStreamArray &HashValues, uint32_t NumHashBuckets) : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {} - void visitUdtSourceLine(UdtSourceLineRecord &Rec) { verifySourceLine(Rec); } + Error visitUdtSourceLine(UdtSourceLineRecord &Rec) override { + return verifySourceLine(Rec); + } - void visitUdtModSourceLine(UdtModSourceLineRecord &Rec) { - verifySourceLine(Rec); + Error visitUdtModSourceLine(UdtModSourceLineRecord &Rec) override { + return verifySourceLine(Rec); } - void visitClass(ClassRecord &Rec) { verify(Rec); } - void visitEnum(EnumRecord &Rec) { verify(Rec); } - void visitInterface(ClassRecord &Rec) { verify(Rec); } - void visitStruct(ClassRecord &Rec) { verify(Rec); } - void visitUnion(UnionRecord &Rec) { verify(Rec); } + Error visitClass(ClassRecord &Rec) override { return verify(Rec); } + Error visitEnum(EnumRecord &Rec) override { return verify(Rec); } + Error visitUnion(UnionRecord &Rec) override { return verify(Rec); } - void visitTypeEnd(const CVRecord &Record) { ++Index; } + Error visitTypeEnd(const CVRecord &Record) override { + ++Index; + return Error::success(); + } private: - template void verify(T &Rec) { + template Error verify(T &Rec) { uint32_t Hash = getTpiHash(Rec); if (Hash && Hash % NumHashBuckets != HashValues[Index]) - parseError(); + return make_error(raw_error_code::invalid_tpi_hash); + return Error::success(); } - template void verifySourceLine(T &Rec) { + template Error verifySourceLine(T &Rec) { char Buf[4]; support::endian::write32le(Buf, Rec.getUDT().getIndex()); uint32_t Hash = hashStringV1(StringRef(Buf, 4)); if (Hash % NumHashBuckets != HashValues[Index]) - parseError(); + return make_error(raw_error_code::invalid_tpi_hash); + return Error::success(); } FixedStreamArray HashValues; @@ -129,11 +134,8 @@ private: // Currently we only verify SRC_LINE records. Error TpiStream::verifyHashValues() { TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets); - Verifier.visitTypeStream(TypeRecords); - if (Verifier.hadError()) - return make_error(raw_error_code::corrupt_file, - "Corrupt TPI hash table."); - return Error::success(); + CVTypeVisitor Visitor(Verifier); + return Visitor.visitTypeStream(TypeRecords); } Error TpiStream::reload() { -- cgit v1.2.3