diff --git a/include/llvm/Bytecode/Archive.h b/include/llvm/Bytecode/Archive.h index 67615b3bef2..943d979cac3 100644 --- a/include/llvm/Bytecode/Archive.h +++ b/include/llvm/Bytecode/Archive.h @@ -396,11 +396,14 @@ class Archive { /// more than one symbol at a time. If \p symbols contains a list of /// undefined symbols in some module, then calling this method is like /// making one complete pass through the archive to resolve symbols but is - /// more efficient than looking at the individual members. + /// more efficient than looking at the individual members. Note that on + /// exit, the symbols resolved by this method will be removed from \p + /// symbols to ensure they are not re-searched on a subsequent call. If + /// you need to retain the list of symbols, make a copy. /// @brief Look up multiple symbols in the archive. void findModulesDefiningSymbols( - const std::set& symbols, ///< Symbols to be sought - std::set& modules ///< The modules matching \p symbols + std::set& symbols, ///< Symbols to be sought + std::set& modules ///< The modules matching \p symbols ); /// @} diff --git a/lib/Archive/ArchiveReader.cpp b/lib/Archive/ArchiveReader.cpp index 615df2bf5f2..6f5b9d36edf 100644 --- a/lib/Archive/ArchiveReader.cpp +++ b/lib/Archive/ArchiveReader.cpp @@ -407,7 +407,7 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) { // Look up multiple symbols in the symbol table and return a set of // ModuleProviders that define those symbols. void -Archive::findModulesDefiningSymbols(const std::set& symbols, +Archive::findModulesDefiningSymbols(std::set& symbols, std::set& result) { assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive"); @@ -462,11 +462,22 @@ Archive::findModulesDefiningSymbols(const std::set& symbols, // At this point we have a valid symbol table (one way or another) so we // just use it to quickly find the symbols requested. - for (std::set::const_iterator I=symbols.begin(), - E=symbols.end(); I != E; ++I) { + for (std::set::iterator I=symbols.begin(), + E=symbols.end(); I != E;) { + // See if this symbol exists ModuleProvider* mp = findModuleDefiningSymbol(*I); if (mp) { + // The symbol exists, insert the ModuleProvider into our result, + // duplicates wil be ignored result.insert(mp); + + // Remove the symbol now that its been resolved, being careful to + // not invalidate our iterator. + std::set::iterator save = I; + ++I; + symbols.erase(save); + } else { + ++I; } } } diff --git a/lib/Bytecode/Archive/ArchiveReader.cpp b/lib/Bytecode/Archive/ArchiveReader.cpp index 615df2bf5f2..6f5b9d36edf 100644 --- a/lib/Bytecode/Archive/ArchiveReader.cpp +++ b/lib/Bytecode/Archive/ArchiveReader.cpp @@ -407,7 +407,7 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) { // Look up multiple symbols in the symbol table and return a set of // ModuleProviders that define those symbols. void -Archive::findModulesDefiningSymbols(const std::set& symbols, +Archive::findModulesDefiningSymbols(std::set& symbols, std::set& result) { assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive"); @@ -462,11 +462,22 @@ Archive::findModulesDefiningSymbols(const std::set& symbols, // At this point we have a valid symbol table (one way or another) so we // just use it to quickly find the symbols requested. - for (std::set::const_iterator I=symbols.begin(), - E=symbols.end(); I != E; ++I) { + for (std::set::iterator I=symbols.begin(), + E=symbols.end(); I != E;) { + // See if this symbol exists ModuleProvider* mp = findModuleDefiningSymbol(*I); if (mp) { + // The symbol exists, insert the ModuleProvider into our result, + // duplicates wil be ignored result.insert(mp); + + // Remove the symbol now that its been resolved, being careful to + // not invalidate our iterator. + std::set::iterator save = I; + ++I; + symbols.erase(save); + } else { + ++I; } } }