Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1078,12 +1078,14 @@ // Handle the `--undefined ` options. for (StringRef S : Config->Undefined) - Symtab->fetchIfLazy(S); + if (InputFile *F = Symtab->fetchIfLazy(S)) + Symtab->addFile(F); // If an entry symbol is in a static archive, pull out that file now // to complete the symbol table. After this, no new names except a // few linker-synthesized ones will be added to the symbol table. - Symtab->fetchIfLazy(Config->Entry); + if (InputFile *F = Symtab->fetchIfLazy(Config->Entry)) + Symtab->addFile(F); // Return if there were name resolution errors. if (errorCount()) Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -46,7 +46,6 @@ using llvm::object::Archive; -class Lazy; class Symbol; // If -reproduce option is given, all input files are written Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -77,7 +77,9 @@ uint8_t Visibility, bool CanOmitFromDynSym, InputFile *File); - template void fetchIfLazy(StringRef Name); + InputFile *fetchLazy(Symbol *Sym); + InputFile *fetchIfLazy(StringRef Name); + void scanVersionScript(); Symbol *find(StringRef Name); Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -309,12 +309,12 @@ if (!Config->GcSections) SS->getFile().IsNeeded = true; } - if (auto *L = dyn_cast(S)) { + if (S->isLazy()) { // An undefined weak will not fetch archive members. See comment on Lazy in // Symbols.h for the details. if (Binding == STB_WEAK) - L->Type = Type; - else if (InputFile *F = L->fetch()) + S->Type = Type; + else if (InputFile *F = Symtab->fetchLazy(S)) addFile(F); } return S; @@ -575,16 +575,21 @@ addFile(F); } -// If we already saw this symbol, force loading its file. -template void SymbolTable::fetchIfLazy(StringRef Name) { - if (Symbol *B = find(Name)) { +InputFile *SymbolTable::fetchLazy(Symbol *L) { + if (auto *S = dyn_cast(L)) + return S->fetch(); + return cast(L)->fetch(); +} + +InputFile *SymbolTable::fetchIfLazy(StringRef Name) { + if (auto *Sym = find(Name)) { // Mark the symbol not to be eliminated by LTO // even if it is a bitcode symbol. - B->IsUsedInRegularObj = true; - if (auto *L = dyn_cast(B)) - if (InputFile *File = L->fetch()) - addFile(File); + Sym->IsUsedInRegularObj = true; + if (Sym->isLazy()) + return fetchLazy(Sym); } + return nullptr; } // Initialize DemangledSyms with a map from demangled symbols to symbol @@ -807,8 +812,3 @@ template void SymbolTable::addShared(StringRef, SharedFile &, const typename ELF64BE::Sym &, uint32_t Alignment, uint32_t); - -template void SymbolTable::fetchIfLazy(StringRef); -template void SymbolTable::fetchIfLazy(StringRef); -template void SymbolTable::fetchIfLazy(StringRef); -template void SymbolTable::fetchIfLazy(StringRef); Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -99,7 +99,7 @@ // True if this is an undefined weak symbol. This only works once // all input files have been added. bool isUndefWeak() const { - // See comment on Lazy for details. + // See comment on lazy symbols for details. return isWeak() && (isUndefined() || isLazy()); } @@ -248,38 +248,27 @@ uint32_t Alignment; }; -// This represents a symbol that is not yet in the link, but we know where to -// find it if needed. If the resolver finds both Undefined and Lazy for the same -// name, it will ask the Lazy to load a file. +// LazyArchive and LazyObject represents a symbols that is not yet in the link, +// but we know where to find it if needed. If the resolver finds both Undefined +// and Lazy for the same name, it will ask the Lazy to load a file. // // A special complication is the handling of weak undefined symbols. They should // not load a file, but we have to remember we have seen both the weak undefined // and the lazy. We represent that with a lazy symbol with a weak binding. This // means that code looking for undefined symbols normally also has to take lazy // symbols into consideration. -class Lazy : public Symbol { -public: - static bool classof(const Symbol *S) { return S->isLazy(); } - - // Returns an object file for this symbol, or a nullptr if the file - // was already returned. - InputFile *fetch(); - -protected: - Lazy(Kind K, InputFile &File, StringRef Name, uint8_t Type) - : Symbol(K, &File, Name, llvm::ELF::STB_GLOBAL, llvm::ELF::STV_DEFAULT, - Type) {} -}; // This class represents a symbol defined in an archive file. It is // created from an archive file header, and it knows how to load an // object file from an archive to replace itself with a defined // symbol. -class LazyArchive : public Lazy { +class LazyArchive : public Symbol { public: LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S, uint8_t Type) - : Lazy(LazyArchiveKind, File, S.getName(), Type), Sym(S) {} + : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL, + llvm::ELF::STV_DEFAULT, Type), + Sym(S) {} static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; } @@ -292,10 +281,11 @@ // LazyObject symbols represents symbols in object files between // --start-lib and --end-lib options. -class LazyObject : public Lazy { +class LazyObject : public Symbol { public: LazyObject(InputFile &File, StringRef Name, uint8_t Type) - : Lazy(LazyObjectKind, File, Name, Type) {} + : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL, + llvm::ELF::STV_DEFAULT, Type) {} static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; } Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -207,12 +207,6 @@ Verstr); } -InputFile *Lazy::fetch() { - if (auto *S = dyn_cast(this)) - return S->fetch(); - return cast(this)->fetch(); -} - ArchiveFile &LazyArchive::getFile() { return *cast(File); } InputFile *LazyArchive::fetch() {