Index: lld/trunk/include/lld/Core/ArchiveLibraryFile.h =================================================================== --- lld/trunk/include/lld/Core/ArchiveLibraryFile.h +++ lld/trunk/include/lld/Core/ArchiveLibraryFile.h @@ -12,6 +12,8 @@ #include "lld/Core/File.h" +#include + namespace lld { /// @@ -36,6 +38,12 @@ virtual error_code parseAllMembers(std::vector> &result) const = 0; + /// Returns a set of all defined symbols in the archive, i.e. all + /// resolvable symbol using this file. + virtual std::set getDefinedSymbols() const { + return std::set(); + } + protected: /// only subclasses of ArchiveLibraryFile can be instantiated ArchiveLibraryFile(StringRef path) : File(path, kindArchiveLibrary) {} Index: lld/trunk/include/lld/Core/InputGraph.h =================================================================== --- lld/trunk/include/lld/Core/InputGraph.h +++ lld/trunk/include/lld/Core/InputGraph.h @@ -19,6 +19,7 @@ #include "lld/Core/File.h" #include "llvm/Option/ArgList.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -67,6 +68,11 @@ /// whether it should iterate over again or terminate or not. void notifyProgress(); + /// Adds an observer of getNextFile(). Each time a new file is about to be + /// returned from getNextFile(), registered observers are called with the file + /// being returned. + void registerObserver(llvm::function_ref fn); + /// \brief Adds a node into the InputGraph void addInputElement(std::unique_ptr); @@ -93,6 +99,7 @@ // Index of the next element to be processed uint32_t _nextElementIndex; InputElement *_currentInputElement; + std::vector> _observers; private: ErrorOr getNextInputElement(); Index: lld/trunk/lib/Core/InputGraph.cpp =================================================================== --- lld/trunk/lib/Core/InputGraph.cpp +++ lld/trunk/lib/Core/InputGraph.cpp @@ -21,9 +21,12 @@ // it will succeed. If not, try to get the next file in the input graph. for (;;) { if (_currentInputElement) { - ErrorOr nextFile = _currentInputElement->getNextFile(); - if (nextFile.getError() != InputGraphError::no_more_files) - return std::move(nextFile); + ErrorOr next = _currentInputElement->getNextFile(); + if (next.getError() != InputGraphError::no_more_files) { + for (llvm::function_ref observer : _observers) + observer(&next.get()); + return std::move(next); + } } ErrorOr elt = getNextInputElement(); @@ -35,6 +38,10 @@ void InputGraph::notifyProgress() { _currentInputElement->notifyProgress(); } +void InputGraph::registerObserver(llvm::function_ref fn) { + _observers.push_back(fn); +} + void InputGraph::addInputElement(std::unique_ptr ie) { _inputArgs.push_back(std::move(ie)); } Index: lld/trunk/lib/ReaderWriter/FileArchive.cpp =================================================================== --- lld/trunk/lib/ReaderWriter/FileArchive.cpp +++ lld/trunk/lib/ReaderWriter/FileArchive.cpp @@ -97,6 +97,14 @@ return _absoluteAtoms; } + /// Returns a set of all defined symbols in the archive. + std::set getDefinedSymbols() const override { + std::set ret; + for (const auto &e : _symbolMemberMap) + ret.insert(e.first); + return ret; + } + protected: error_code instantiateMember(Archive::child_iterator member, Index: lld/trunk/unittests/DriverTests/InputGraphTest.cpp =================================================================== --- lld/trunk/unittests/DriverTests/InputGraphTest.cpp +++ lld/trunk/unittests/DriverTests/InputGraphTest.cpp @@ -191,3 +191,18 @@ EXPECT_EQ("file6", getNext()); expectEnd(); } + +TEST_F(InputGraphTest, Observer) { + std::vector files; + _graph->registerObserver([&](File *file) { files.push_back(file->path()); }); + + _graph->addInputElement(createFile1("file1")); + _graph->addInputElement(createFile1("file2")); + EXPECT_EQ("file1", getNext()); + EXPECT_EQ("file2", getNext()); + expectEnd(); + + EXPECT_EQ(2U, files.size()); + EXPECT_EQ("file1", files[0]); + EXPECT_EQ("file2", files[1]); +}