Index: lld/COFF/PDB.cpp =================================================================== --- lld/COFF/PDB.cpp +++ lld/COFF/PDB.cpp @@ -33,7 +33,6 @@ #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" -#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" #include "llvm/Object/COFF.h" @@ -97,12 +96,6 @@ /// table. DebugStringTableSubsection PDBStrTab; - // Follow type servers. If the same type server is encountered more than once - // for this instance of `PDBTypeServerHandler` (for example if many object - // files reference the same TypeServer), the types from the TypeServer will - // only be visited once. - pdb::PDBTypeServerHandler TSHandler; - llvm::SmallString<128> NativePath; std::vector SectionMap; @@ -163,15 +156,14 @@ // archive, look next to the archive path. StringRef LocalPath = !File->ParentName.empty() ? File->ParentName : File->getName(); - TSHandler.addSearchPath(sys::path::parent_path(LocalPath)); + (void)LocalPath; // FIXME: Implement type server handling here. BinaryByteStream Stream(Data, support::little); CVTypeArray Types; BinaryStreamReader Reader(Stream); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); - if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, TypeIndexMap, - &TSHandler, Types)) + if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, TypeIndexMap, Types)) fatal(Err, "codeview::mergeTypeStreams failed"); } Index: lld/test/COFF/pdb-type-server-missing.yaml =================================================================== --- lld/test/COFF/pdb-type-server-missing.yaml +++ lld/test/COFF/pdb-type-server-missing.yaml @@ -1,6 +1,9 @@ # This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an # adjacent type server PDB. Test that LLD fails gracefully on it. +# FIXME: Type server handling was removed from LLVM. +# XFAIL: * + # FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug # info in the object with the missing PDB. Index: llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -17,7 +17,6 @@ namespace llvm { namespace codeview { class TypeCollection; -class TypeServerHandler; class TypeVisitorCallbacks; enum VisitorDataSource { @@ -31,11 +30,9 @@ Error visitTypeRecord(CVType &Record, TypeIndex Index, TypeVisitorCallbacks &Callbacks, - VisitorDataSource Source = VDS_BytesPresent, - TypeServerHandler *TS = nullptr); + VisitorDataSource Source = VDS_BytesPresent); Error visitTypeRecord(CVType &Record, TypeVisitorCallbacks &Callbacks, - VisitorDataSource Source = VDS_BytesPresent, - TypeServerHandler *TS = nullptr); + VisitorDataSource Source = VDS_BytesPresent); Error visitMemberRecord(CVMemberRecord Record, TypeVisitorCallbacks &Callbacks, VisitorDataSource Source = VDS_BytesPresent); @@ -46,12 +43,9 @@ TypeVisitorCallbacks &Callbacks); Error visitTypeStream(const CVTypeArray &Types, TypeVisitorCallbacks &Callbacks, - VisitorDataSource Source = VDS_BytesPresent, - TypeServerHandler *TS = nullptr); -Error visitTypeStream(CVTypeRange Types, TypeVisitorCallbacks &Callbacks, - TypeServerHandler *TS = nullptr); -Error visitTypeStream(TypeCollection &Types, TypeVisitorCallbacks &Callbacks, - TypeServerHandler *TS = nullptr); + VisitorDataSource Source = VDS_BytesPresent); +Error visitTypeStream(CVTypeRange Types, TypeVisitorCallbacks &Callbacks); +Error visitTypeStream(TypeCollection &Types, TypeVisitorCallbacks &Callbacks); } // end namespace codeview } // end namespace llvm Index: llvm/include/llvm/DebugInfo/CodeView/TypeServerHandler.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeServerHandler.h +++ /dev/null @@ -1,38 +0,0 @@ -//===- TypeServerHandler.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H -#define LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H - -#include "llvm/Support/Error.h" - -namespace llvm { -namespace codeview { - -class TypeServer2Record; -class TypeVisitorCallbacks; - -class TypeServerHandler { -public: - virtual ~TypeServerHandler() = default; - - /// Handle a TypeServer record. If the implementation returns true - /// the record will not be processed by the top-level visitor. If - /// it returns false, it will be processed. If it returns an Error, - /// then the top-level visitor will fail. - virtual Expected handle(TypeServer2Record &TS, - TypeVisitorCallbacks &Callbacks) { - return false; - } -}; - -} // end namespace codeview -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H Index: llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -19,7 +19,6 @@ namespace codeview { class TypeIndex; -class TypeServerHandler; class TypeTableBuilder; /// \brief Merge one set of type records into another. This method assumes @@ -40,7 +39,7 @@ /// appropriate error code. Error mergeTypeRecords(TypeTableBuilder &Dest, SmallVectorImpl &SourceToDest, - TypeServerHandler *Handler, const CVTypeArray &Types); + const CVTypeArray &Types); /// \brief Merge one set of id records into another. This method assumes /// that all records are id records, and there are no Type records present. @@ -65,7 +64,7 @@ /// appropriate error code. Error mergeIdRecords(TypeTableBuilder &Dest, ArrayRef Types, SmallVectorImpl &SourceToDest, - const CVTypeArray &Ids); + const CVTypeArray &Ids); /// \brief Merge a unified set of type and id records, splitting them into /// separate output streams. @@ -88,8 +87,7 @@ Error mergeTypeAndIdRecords(TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes, SmallVectorImpl &SourceToDest, - TypeServerHandler *Handler, - const CVTypeArray &IdsAndTypes); + const CVTypeArray &IdsAndTypes); } // end namespace codeview } // end namespace llvm Index: llvm/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h +++ /dev/null @@ -1,46 +0,0 @@ -//===- PDBTypeServerHandler.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_PDB_PDBTYPESERVERHANDLER_H -#define LLVM_DEBUGINFO_PDB_PDBTYPESERVERHANDLER_H - -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" -#include "llvm/DebugInfo/PDB/Native/NativeSession.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" - -#include -#include - -namespace llvm { -namespace pdb { -class NativeSession; - -class PDBTypeServerHandler : public codeview::TypeServerHandler { -public: - PDBTypeServerHandler(bool RevisitAlways = false); - - void addSearchPath(StringRef Path); - Expected handle(codeview::TypeServer2Record &TS, - codeview::TypeVisitorCallbacks &Callbacks) override; - -private: - Expected handleInternal(PDBFile &File, - codeview::TypeVisitorCallbacks &Callbacks); - - bool RevisitAlways; - std::unique_ptr Session; - StringSet<> SearchPaths; -}; -} -} - -#endif Index: llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -14,7 +14,6 @@ #include "llvm/DebugInfo/CodeView/TypeCollection.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" -#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamReader.h" @@ -42,13 +41,6 @@ return Error::success(); } -static Expected deserializeTypeServerRecord(CVType &Record) { - TypeServer2Record R(TypeRecordKind::TypeServer2); - if (auto EC = TypeDeserializer::deserializeAs(Record, R)) - return std::move(EC); - return R; -} - static Error visitMemberRecord(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks) { if (auto EC = Callbacks.visitMemberBegin(Record)) @@ -84,8 +76,6 @@ public: explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks); - void addTypeServerHandler(TypeServerHandler &Handler); - Error visitTypeRecord(CVType &Record, TypeIndex Index); Error visitTypeRecord(CVType &Record); @@ -98,45 +88,15 @@ Error visitFieldListMemberStream(BinaryStreamReader &Stream); private: - Expected handleTypeServer(CVType &Record); Error finishVisitation(CVType &Record); /// The interface to the class that gets notified of each visitation. TypeVisitorCallbacks &Callbacks; - - TinyPtrVector Handlers; }; CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks) : Callbacks(Callbacks) {} -void CVTypeVisitor::addTypeServerHandler(TypeServerHandler &Handler) { - Handlers.push_back(&Handler); -} - -Expected CVTypeVisitor::handleTypeServer(CVType &Record) { - if (Record.Type == TypeLeafKind::LF_TYPESERVER2 && !Handlers.empty()) { - auto TS = deserializeTypeServerRecord(Record); - if (!TS) - return TS.takeError(); - - for (auto Handler : Handlers) { - auto ExpectedResult = Handler->handle(*TS, Callbacks); - // If there was an error, return the error. - if (!ExpectedResult) - return ExpectedResult.takeError(); - - // If the handler processed the record, return success. - if (*ExpectedResult) - return true; - - // Otherwise keep searching for a handler, eventually falling out and - // using the default record handler. - } - } - return false; -} - Error CVTypeVisitor::finishVisitation(CVType &Record) { switch (Record.Type) { default: @@ -163,12 +123,6 @@ } Error CVTypeVisitor::visitTypeRecord(CVType &Record, TypeIndex Index) { - auto ExpectedResult = handleTypeServer(Record); - if (!ExpectedResult) - return ExpectedResult.takeError(); - if (*ExpectedResult) - return Error::success(); - if (auto EC = Callbacks.visitTypeBegin(Record, Index)) return EC; @@ -176,12 +130,6 @@ } Error CVTypeVisitor::visitTypeRecord(CVType &Record) { - auto ExpectedResult = handleTypeServer(Record); - if (!ExpectedResult) - return ExpectedResult.takeError(); - if (*ExpectedResult) - return Error::success(); - if (auto EC = Callbacks.visitTypeBegin(Record)) return EC; @@ -271,52 +219,37 @@ Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index, TypeVisitorCallbacks &Callbacks, - VisitorDataSource Source, - TypeServerHandler *TS) { + VisitorDataSource Source) { VisitHelper V(Callbacks, Source); - if (TS) - V.Visitor.addTypeServerHandler(*TS); return V.Visitor.visitTypeRecord(Record, Index); } Error llvm::codeview::visitTypeRecord(CVType &Record, TypeVisitorCallbacks &Callbacks, - VisitorDataSource Source, - TypeServerHandler *TS) { + VisitorDataSource Source) { VisitHelper V(Callbacks, Source); - if (TS) - V.Visitor.addTypeServerHandler(*TS); return V.Visitor.visitTypeRecord(Record); } Error llvm::codeview::visitTypeStream(const CVTypeArray &Types, TypeVisitorCallbacks &Callbacks, - VisitorDataSource Source, - TypeServerHandler *TS) { + VisitorDataSource Source) { VisitHelper V(Callbacks, Source); - if (TS) - V.Visitor.addTypeServerHandler(*TS); return V.Visitor.visitTypeStream(Types); } Error llvm::codeview::visitTypeStream(CVTypeRange Types, - TypeVisitorCallbacks &Callbacks, - TypeServerHandler *TS) { + TypeVisitorCallbacks &Callbacks) { VisitHelper V(Callbacks, VDS_BytesPresent); - if (TS) - V.Visitor.addTypeServerHandler(*TS); return V.Visitor.visitTypeStream(Types); } Error llvm::codeview::visitTypeStream(TypeCollection &Types, - TypeVisitorCallbacks &Callbacks, - TypeServerHandler *TS) { + TypeVisitorCallbacks &Callbacks) { // When the internal visitor calls Types.getType(Index) the interface is // required to return a CVType with the bytes filled out. So we can assume // that the bytes will be present when individual records are visited. VisitHelper V(Callbacks, VDS_BytesPresent); - if (TS) - V.Visitor.addTypeServerHandler(*TS); return V.Visitor.visitTypeStream(Types); } Index: llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -59,9 +59,8 @@ /// looking at the record kind. class TypeStreamMerger : public TypeVisitorCallbacks { public: - explicit TypeStreamMerger(SmallVectorImpl &SourceToDest, - TypeServerHandler *Handler) - : Handler(Handler), IndexMap(SourceToDest) { + explicit TypeStreamMerger(SmallVectorImpl &SourceToDest) + : IndexMap(SourceToDest) { SourceToDest.clear(); } @@ -71,10 +70,10 @@ Error visitTypeEnd(CVType &Record) override; Error mergeTypesAndIds(TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes, - const CVTypeArray &IdsAndTypes); + const CVTypeArray &IdsAndTypes); Error mergeIdRecords(TypeTableBuilder &Dest, ArrayRef TypeSourceToDest, - const CVTypeArray &Ids); + const CVTypeArray &Ids); Error mergeTypeRecords(TypeTableBuilder &Dest, const CVTypeArray &Types); private: @@ -153,7 +152,6 @@ TypeTableBuilder *DestIdStream = nullptr; TypeTableBuilder *DestTypeStream = nullptr; - TypeServerHandler *Handler = nullptr; // If we're only mapping id records, this array contains the mapping for // type records. @@ -256,7 +254,7 @@ } Error TypeStreamMerger::mergeTypeRecords(TypeTableBuilder &Dest, - const CVTypeArray &Types) { + const CVTypeArray &Types) { DestTypeStream = &Dest; return doit(Types); @@ -264,7 +262,7 @@ Error TypeStreamMerger::mergeIdRecords(TypeTableBuilder &Dest, ArrayRef TypeSourceToDest, - const CVTypeArray &Ids) { + const CVTypeArray &Ids) { DestIdStream = &Dest; TypeLookup = TypeSourceToDest; @@ -288,7 +286,7 @@ // would buy us much since it's already pretty fast, but it's probably worth // a few cycles. if (auto EC = - codeview::visitTypeStream(Types, *this, VDS_BytesExternal, Handler)) + codeview::visitTypeStream(Types, *this, VDS_BytesExternal)) return EC; // If we found bad indices but no other errors, try doing another pass and see @@ -305,7 +303,7 @@ CurIndex = TypeIndex(TypeIndex::FirstNonSimpleIndex); if (auto EC = - codeview::visitTypeStream(Types, *this, VDS_BytesExternal, Handler)) + codeview::visitTypeStream(Types, *this, VDS_BytesExternal)) return EC; assert(NumBadIndices <= BadIndicesRemaining && @@ -323,24 +321,22 @@ Error llvm::codeview::mergeTypeRecords(TypeTableBuilder &Dest, SmallVectorImpl &SourceToDest, - TypeServerHandler *Handler, - const CVTypeArray &Types) { - TypeStreamMerger M(SourceToDest, Handler); + const CVTypeArray &Types) { + TypeStreamMerger M(SourceToDest); return M.mergeTypeRecords(Dest, Types); } Error llvm::codeview::mergeIdRecords(TypeTableBuilder &Dest, ArrayRef TypeSourceToDest, SmallVectorImpl &SourceToDest, - const CVTypeArray &Ids) { - TypeStreamMerger M(SourceToDest, nullptr); + const CVTypeArray &Ids) { + TypeStreamMerger M(SourceToDest); return M.mergeIdRecords(Dest, TypeSourceToDest, Ids); } Error llvm::codeview::mergeTypeAndIdRecords( TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes, - SmallVectorImpl &SourceToDest, TypeServerHandler *Handler, - const CVTypeArray &IdsAndTypes) { - TypeStreamMerger M(SourceToDest, Handler); + SmallVectorImpl &SourceToDest, const CVTypeArray &IdsAndTypes) { + TypeStreamMerger M(SourceToDest); return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes); } Index: llvm/lib/DebugInfo/PDB/CMakeLists.txt =================================================================== --- llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -52,7 +52,6 @@ Native/PDBFileBuilder.cpp Native/PDBStringTable.cpp Native/PDBStringTableBuilder.cpp - Native/PDBTypeServerHandler.cpp Native/PublicsStream.cpp Native/PublicsStreamBuilder.cpp Native/RawError.cpp Index: llvm/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//===- PDBTypeServerHandler.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Handles CodeView LF_TYPESERVER2 records by attempting to locate a matching -// PDB file, then loading the PDB file and visiting all types from the -// referenced PDB using the original supplied visitor. -// -// The net effect of this is that when visiting a PDB containing a TypeServer -// record, the TypeServer record is "replaced" with all of the records in -// the referenced PDB file. If a single instance of PDBTypeServerHandler -// encounters the same TypeServer multiple times (for example reusing one -// PDBTypeServerHandler across multiple visitations of distinct object files or -// PDB files), PDBTypeServerHandler will optionally revisit all the records -// again, or simply consume the record and do nothing. -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h" - -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/PDB/GenericError.h" -#include "llvm/DebugInfo/PDB/Native/InfoStream.h" -#include "llvm/DebugInfo/PDB/Native/NativeSession.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/TpiStream.h" -#include "llvm/DebugInfo/PDB/PDB.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::pdb; - -static void ignoreErrors(Error EC) { - llvm::handleAllErrors(std::move(EC), [&](ErrorInfoBase &EIB) {}); -} - -PDBTypeServerHandler::PDBTypeServerHandler(bool RevisitAlways) - : RevisitAlways(RevisitAlways) {} - -void PDBTypeServerHandler::addSearchPath(StringRef Path) { - if (Path.empty() || !sys::fs::is_directory(Path)) - return; - - SearchPaths.insert(Path); -} - -Expected -PDBTypeServerHandler::handleInternal(PDBFile &File, - TypeVisitorCallbacks &Callbacks) { - auto ExpectedTpi = File.getPDBTpiStream(); - if (!ExpectedTpi) - return ExpectedTpi.takeError(); - - // For handling a type server, we should be using whatever the callback array - // was that is being used for the original file. We shouldn't allow the - // visitor to arbitrarily stick a deserializer in there. - if (auto EC = codeview::visitTypeStream(ExpectedTpi->typeArray(), Callbacks, - VDS_BytesExternal)) - return std::move(EC); - - return true; -} - -Expected PDBTypeServerHandler::handle(TypeServer2Record &TS, - TypeVisitorCallbacks &Callbacks) { - if (Session) { - // If we've already handled this TypeServer and we only want to handle each - // TypeServer once, consume the record without doing anything. - if (!RevisitAlways) - return true; - - return handleInternal(Session->getPDBFile(), Callbacks); - } - - StringRef File = sys::path::filename(TS.Name); - if (File.empty()) - return make_error( - cv_error_code::corrupt_record, - "TypeServer2Record does not contain filename!"); - - for (auto &Path : SearchPaths) { - SmallString<64> PathStr = Path.getKey(); - sys::path::append(PathStr, File); - if (!sys::fs::exists(PathStr)) - continue; - - std::unique_ptr ThisSession; - if (auto EC = loadDataForPDB(PDB_ReaderType::Native, PathStr, ThisSession)) { - // It is not an error if this PDB fails to load, it just means that it - // doesn't match and we should continue searching. - ignoreErrors(std::move(EC)); - continue; - } - - std::unique_ptr NS( - static_cast(ThisSession.release())); - PDBFile &File = NS->getPDBFile(); - auto ExpectedInfo = File.getPDBInfoStream(); - // All PDB Files should have an Info stream. - if (!ExpectedInfo) - return ExpectedInfo.takeError(); - - // Just because a file with a matching name was found and it was an actual - // PDB file doesn't mean it matches. For it to match the InfoStream's GUID - // must match the GUID specified in the TypeServer2 record. - ArrayRef GuidBytes(ExpectedInfo->getGuid().Guid); - StringRef GuidStr(reinterpret_cast(GuidBytes.begin()), - GuidBytes.size()); - if (GuidStr != TS.Guid) - continue; - - Session = std::move(NS); - return handleInternal(File, Callbacks); - } - - // We couldn't find a matching PDB, so let it be handled by someone else. - return make_error(generic_error_code::type_server_not_found, - File); -} Index: llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp +++ llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp @@ -14,7 +14,6 @@ #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" Index: llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp =================================================================== --- llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -956,8 +956,8 @@ SmallVector IdMap; if (File.hasPDBTpiStream()) { auto &Tpi = ExitOnErr(File.getPDBTpiStream()); - ExitOnErr(codeview::mergeTypeRecords(MergedTpi, TypeMap, nullptr, - Tpi.typeArray())); + ExitOnErr( + codeview::mergeTypeRecords(MergedTpi, TypeMap, Tpi.typeArray())); } if (File.hasPDBIpiStream()) { auto &Ipi = ExitOnErr(File.getPDBIpiStream()); Index: llvm/tools/llvm-readobj/COFFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/COFFDumper.cpp +++ llvm/tools/llvm-readobj/COFFDumper.cpp @@ -1215,8 +1215,7 @@ error(object_error::parse_failed); } SmallVector SourceToDest; - if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, nullptr, - Types)) + if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types)) return error(std::move(EC)); } } Index: llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp =================================================================== --- llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp +++ llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp @@ -13,7 +13,6 @@ #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeSerializer.h" -#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" @@ -402,4 +401,4 @@ StringRef Name = Types.getTypeName(IndexOne); EXPECT_EQ("const FooClass", Name); -} \ No newline at end of file +} Index: llvm/unittests/DebugInfo/PDB/CMakeLists.txt =================================================================== --- llvm/unittests/DebugInfo/PDB/CMakeLists.txt +++ llvm/unittests/DebugInfo/PDB/CMakeLists.txt @@ -10,11 +10,10 @@ StringTableBuilderTest.cpp MSFBuilderTest.cpp PDBApiTest.cpp - TypeServerHandlerTest.cpp ) add_llvm_unittest(DebugInfoPDBTests ${DebugInfoPDBSources} ) -target_link_libraries(DebugInfoPDBTests LLVMTestingSupport) \ No newline at end of file +target_link_libraries(DebugInfoPDBTests LLVMTestingSupport) Index: llvm/unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp =================================================================== --- llvm/unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp +++ /dev/null @@ -1,183 +0,0 @@ -//===- llvm/unittest/DebugInfo/PDB/TypeServerHandlerTest.cpp --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" -#include "llvm/DebugInfo/CodeView/TypeSerializer.h" -#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/PDB/Native/RawTypes.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Error.h" -#include "llvm/Testing/Support/Error.h" - -#include "gtest/gtest.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::pdb; - -namespace { - -constexpr uint8_t Guid[] = {0x2a, 0x2c, 0x1c, 0x2a, 0xcb, 0x9e, 0x48, 0x18, - 0x82, 0x82, 0x7a, 0x87, 0xc3, 0xfe, 0x16, 0xe8}; -StringRef GuidStr(reinterpret_cast(Guid), - llvm::array_lengthof(Guid)); - -constexpr const char *Name = "Test Name"; -constexpr int Age = 1; - -class MockTypeServerHandler : public TypeServerHandler { -public: - explicit MockTypeServerHandler(bool HandleAlways) - : HandleAlways(HandleAlways) {} - - Expected handle(TypeServer2Record &TS, - TypeVisitorCallbacks &Callbacks) override { - if (TS.Age != Age || TS.Guid != GuidStr || TS.Name != Name) - return make_error(cv_error_code::corrupt_record, - "Invalid TypeServer record!"); - - if (Handled && !HandleAlways) - return false; - - Handled = true; - return true; - } - - bool Handled = false; - bool HandleAlways; -}; - -class MockTypeVisitorCallbacks : public TypeVisitorCallbacks { -public: - enum class State { - Ready, - VisitTypeBegin, - VisitKnownRecord, - VisitTypeEnd, - }; - Error visitTypeBegin(CVType &CVT) override { - if (S != State::Ready) - return make_error(cv_error_code::unspecified, - "Invalid visitor state!"); - - S = State::VisitTypeBegin; - return Error::success(); - } - - Error visitKnownRecord(CVType &CVT, TypeServer2Record &TS) override { - if (S != State::VisitTypeBegin) - return make_error(cv_error_code::unspecified, - "Invalid visitor state!"); - - S = State::VisitKnownRecord; - return Error::success(); - } - - Error visitTypeEnd(CVType &CVT) override { - if (S != State::VisitKnownRecord) - return make_error(cv_error_code::unspecified, - "Invalid visitor state!"); - - S = State::VisitTypeEnd; - return Error::success(); - } - - State S = State::Ready; -}; - -class TypeServerHandlerTest : public testing::Test { -public: - void SetUp() override { - TypeServer2Record R(TypeRecordKind::TypeServer2); - R.Age = Age; - R.Guid = GuidStr; - R.Name = Name; - - TypeTableBuilder Builder(Allocator); - Builder.writeKnownType(R); - TypeServerRecord.RecordData = Builder.records().front(); - TypeServerRecord.Type = TypeLeafKind::LF_TYPESERVER2; - } - -protected: - BumpPtrAllocator Allocator; - CVType TypeServerRecord; -}; - -// Test that when no type server handler is registered, it gets handled by the -// normal -// visitor callbacks. -TEST_F(TypeServerHandlerTest, VisitRecordNoTypeServer) { - MockTypeVisitorCallbacks C2; - MockTypeVisitorCallbacks C1; - TypeVisitorCallbackPipeline Pipeline; - - Pipeline.addCallbackToPipeline(C1); - Pipeline.addCallbackToPipeline(C2); - - EXPECT_THAT_ERROR(codeview::visitTypeRecord(TypeServerRecord, Pipeline), - Succeeded()); - - EXPECT_EQ(MockTypeVisitorCallbacks::State::VisitTypeEnd, C1.S); - EXPECT_EQ(MockTypeVisitorCallbacks::State::VisitTypeEnd, C2.S); -} - -// Test that when a TypeServerHandler is registered, it gets consumed by the -// handler if and only if the handler returns true. -TEST_F(TypeServerHandlerTest, VisitRecordWithTypeServerOnce) { - MockTypeServerHandler Handler(false); - - MockTypeVisitorCallbacks C1; - - // Our mock server returns true the first time. - EXPECT_THAT_ERROR(codeview::visitTypeRecord(TypeServerRecord, C1, - codeview::VDS_BytesExternal, - &Handler), - Succeeded()); - EXPECT_TRUE(Handler.Handled); - EXPECT_EQ(MockTypeVisitorCallbacks::State::Ready, C1.S); - - // And false the second time. - EXPECT_THAT_ERROR(codeview::visitTypeRecord(TypeServerRecord, C1, - codeview::VDS_BytesExternal, - &Handler), - Succeeded()); - EXPECT_TRUE(Handler.Handled); - EXPECT_EQ(MockTypeVisitorCallbacks::State::VisitTypeEnd, C1.S); -} - -// Test that when a type server handler is registered, if the handler keeps -// returning true, it will keep getting consumed by the handler and not go -// to the default processor. -TEST_F(TypeServerHandlerTest, VisitRecordWithTypeServerAlways) { - MockTypeServerHandler Handler(true); - - MockTypeVisitorCallbacks C1; - - EXPECT_THAT_ERROR(codeview::visitTypeRecord(TypeServerRecord, C1, - codeview::VDS_BytesExternal, - &Handler), - Succeeded()); - EXPECT_TRUE(Handler.Handled); - EXPECT_EQ(MockTypeVisitorCallbacks::State::Ready, C1.S); - - EXPECT_THAT_ERROR(codeview::visitTypeRecord(TypeServerRecord, C1, - codeview::VDS_BytesExternal, - &Handler), - Succeeded()); - EXPECT_TRUE(Handler.Handled); - EXPECT_EQ(MockTypeVisitorCallbacks::State::Ready, C1.S); -} - -} // end anonymous namespace