diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Bytecode/Reader/Reader.h | 2 | ||||
-rw-r--r-- | lib/Linker/LinkArchives.cpp | 35 | ||||
-rw-r--r-- | lib/Linker/LinkItems.cpp | 13 |
3 files changed, 32 insertions, 18 deletions
diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h index b03e8e688c..b8b146698a 100644 --- a/lib/Bytecode/Reader/Reader.h +++ b/lib/Bytecode/Reader/Reader.h @@ -181,7 +181,7 @@ public: /// @brief Release our hold on the generated module Module* releaseModule(std::string *ErrInfo = 0) { // Since we're losing control of this Module, we must hand it back complete - Module *M = ModuleProvider::releaseModule(); + Module *M = ModuleProvider::releaseModule(ErrInfo); freeState(); return M; } diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp index 63e263abb2..152b0b1e7b 100644 --- a/lib/Linker/LinkArchives.cpp +++ b/lib/Linker/LinkArchives.cpp @@ -124,8 +124,12 @@ Linker::LinkInArchive(const sys::Path &Filename) { // variable is used to "set_subtract" from the set of undefined symbols. std::set<std::string> NotDefinedByArchive; - // While we are linking in object files, loop. - while (true) { + // Save the current set of undefined symbols, because we may have to make + // multiple passes over the archive: + std::set<std::string> CurrentlyUndefinedSymbols; + + do { + CurrentlyUndefinedSymbols = UndefinedSymbols; // Find the modules we need to link into the target module std::set<ModuleProvider*> Modules; @@ -149,17 +153,26 @@ Linker::LinkInArchive(const sys::Path &Filename) { I != E; ++I) { // Get the module we must link in. - std::auto_ptr<Module> AutoModule( (*I)->releaseModule() ); + std::string moduleErrorMsg; + std::auto_ptr<Module> AutoModule((*I)->releaseModule( &moduleErrorMsg )); Module* aModule = AutoModule.get(); - verbose(" Linking in module: " + aModule->getModuleIdentifier()); - - // Link it in - if (LinkInModule(aModule)) - return error("Cannot link in module '" + - aModule->getModuleIdentifier() + "': " + Error); + if (aModule != NULL) { + verbose(" Linking in module: " + aModule->getModuleIdentifier()); + + // Link it in + if (LinkInModule(aModule, &moduleErrorMsg)) { + return error("Cannot link in module '" + + aModule->getModuleIdentifier() + "': " + moduleErrorMsg); + } + } else { + // (scottm) NOTE: For some reason, Modules.empty() isn't entirely + // accurrate, least with gcc 4.1.2 on Debian and doesn't return true + // when it ought. Consequently, aModule can be NULL -- ignore it for + // the time being, since it seems relatively benign. + } } - + // Get the undefined symbols from the aggregate module. This recomputes the // symbols we still need after the new modules have been linked in. GetAllUndefinedSymbols(Composite, UndefinedSymbols); @@ -175,7 +188,7 @@ Linker::LinkInArchive(const sys::Path &Filename) { // archive. if (UndefinedSymbols.empty()) break; - } + } while (CurrentlyUndefinedSymbols != UndefinedSymbols); return false; } diff --git a/lib/Linker/LinkItems.cpp b/lib/Linker/LinkItems.cpp index aaa87dcb37..22e6614405 100644 --- a/lib/Linker/LinkItems.cpp +++ b/lib/Linker/LinkItems.cpp @@ -32,10 +32,10 @@ Linker::LinkInItems(const ItemList& Items, ItemList& NativeItems) { I != E; ++I) { if (I->second) { // Link in the library suggested. - bool is_file = true; - if (LinkInLibrary(I->first,is_file)) + bool is_bytecode = true; + if (LinkInLibrary(I->first,is_bytecode)) return true; - if (!is_file) + if (!is_bytecode) NativeItems.push_back(*I); } else { // Link in the file suggested @@ -61,8 +61,8 @@ Linker::LinkInItems(const ItemList& Items, ItemList& NativeItems) { /// LinkInLibrary - links one library into the HeadModule. /// -bool Linker::LinkInLibrary(const std::string& Lib, bool& is_file) { - is_file = false; +bool Linker::LinkInLibrary(const std::string& Lib, bool& is_bytecode) { + is_bytecode = false; // Determine where this library lives. sys::Path Pathname = FindLib(Lib); if (Pathname.isEmpty()) @@ -77,11 +77,12 @@ bool Linker::LinkInLibrary(const std::string& Lib, bool& is_file) { // LLVM ".so" file. if (LinkInFile(Pathname)) return error("Cannot link file '" + Pathname.toString() + "'"); - is_file = true; + is_bytecode = true; break; case sys::ArchiveFileType: if (LinkInArchive(Pathname)) return error("Cannot link archive '" + Pathname.toString() + "'"); + is_bytecode = true; break; default: return warning("Supposed library '" + Lib + "' isn't a library."); |