diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1408,13 +1408,13 @@ } std::vector syms; - symtab->forEachSymbol([&](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) { // Calling Sym->fetch() from here is not safe because it may // add new symbols to the symbol table, invalidating the // current iterator. So we just keep a note. if (pat->match(sym->getName())) syms.push_back(sym); - }); + } for (Symbol *sym : syms) handleUndefined(sym); @@ -1440,10 +1440,10 @@ // result, the passes after the symbol resolution won't see any // symbols of type CommonSymbol. static void replaceCommonSymbols() { - symtab->forEachSymbol([](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) { auto *s = dyn_cast(sym); if (!s) - return; + continue; auto *bss = make("COMMON", s->size, s->alignment); bss->file = s->file; @@ -1451,7 +1451,7 @@ inputSections.push_back(bss); s->replace(Defined{s->file, s->getName(), s->binding, s->stOther, s->type, /*value=*/0, s->size, bss}); - }); + } } // If all references to a DSO happen to be weak, the DSO is not added @@ -1459,15 +1459,15 @@ // created from the DSO. Otherwise, they become dangling references // that point to a non-existent DSO. static void demoteSharedSymbols() { - symtab->forEachSymbol([](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) { auto *s = dyn_cast(sym); if (!s || s->getFile().isNeeded) - return; + continue; bool used = s->used; s->replace(Undefined{nullptr, s->getName(), STB_WEAK, s->stOther, s->type}); s->used = used; - }); + } } // The section referred to by `s` is considered address-significant. Set the @@ -1503,10 +1503,9 @@ // Symbols in the dynsym could be address-significant in other executables // or DSOs, so we conservatively mark them as address-significant. - symtab->forEachSymbol([&](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) if (sym->includeInDynsym()) markAddrsig(sym); - }); // Visit the address-significance table in each object file and mark each // referenced symbol as address-significant. diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -145,12 +145,12 @@ config->ltoPartitions); // Initialize usedStartStop. - symtab->forEachSymbol([&](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) { StringRef s = sym->getName(); for (StringRef prefix : {"__start_", "__stop_"}) if (s.startswith(prefix)) usedStartStop.insert(s.substr(prefix.size())); - }); + } } BitcodeCompiler::~BitcodeCompiler() = default; diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -219,10 +219,9 @@ // Preserve externally-visible symbols if the symbols defined by this // file can interrupt other ELF file's symbols at runtime. - symtab->forEachSymbol([&](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) if (sym->includeInDynsym() && sym->partition == partition) markSymbol(sym); - }); // If this isn't the main partition, that's all that we need to preserve. if (partition != 1) { @@ -330,11 +329,10 @@ sec->markLive(); // If a DSO defines a symbol referenced in a regular object, it is needed. - symtab->forEachSymbol([](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) if (auto *s = dyn_cast(sym)) if (s->isUsedInRegularObj && !s->isWeak()) s->getFile().isNeeded = true; - }); return; } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -799,10 +799,11 @@ break; } if (!s) - symtab->forEachSymbol([&](Symbol *sym) { - if (!s && canSuggestExternCForCXX(name, sym->getName())) + for (Symbol *sym : symtab->symbols()) + if (canSuggestExternCForCXX(name, sym->getName())) { s = sym; - }); + break; + } if (s) { pre_hint = " to declare "; post_hint = " as extern \"C\"?"; diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -32,15 +32,19 @@ // add*() functions, which are called by input files as they are parsed. There // is one add* function per symbol type. class SymbolTable { -public: - void wrap(Symbol *sym, Symbol *real, Symbol *wrap); + struct FilterOutPlaceholder { + bool operator()(Symbol *S) const { return !S->isPlaceholder(); } + }; + using iterator = llvm::filter_iterator::const_iterator, + FilterOutPlaceholder>; - void forEachSymbol(llvm::function_ref fn) { - for (Symbol *sym : symVector) - if (!sym->isPlaceholder()) - fn(sym); +public: + llvm::iterator_range symbols() const { + return llvm::make_filter_range(symVector, FilterOutPlaceholder()); } + void wrap(Symbol *sym, Symbol *real, Symbol *wrap); + Symbol *insert(StringRef name); Symbol *addSymbol(const Symbol &newSym); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1238,10 +1238,9 @@ // We want both global and local symbols. We get the global ones from the // symbol table and iterate the object files for the local ones. - symtab->forEachSymbol([&](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) if (!sym->isLazy()) addSym(*sym); - }); for (InputFile *file : objectFiles) for (Symbol *sym : file->getSymbols()) @@ -1734,8 +1733,8 @@ for (Partition &part : partitions) finalizeSynthetic(part.ehFrame); - symtab->forEachSymbol( - [](Symbol *s) { s->isPreemptible = computeIsPreemptible(*s); }); + for (Symbol *sym : symtab->symbols()) + sym->isPreemptible = computeIsPreemptible(*sym); // Change values of linker-script-defined symbols from placeholders (assigned // by declareSymbols) to actual definitions. @@ -1769,19 +1768,18 @@ return symtab->soNames.count(needed); }); - symtab->forEachSymbol([](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) if (sym->isUndefined() && !sym->isWeak()) if (auto *f = dyn_cast_or_null(sym->file)) if (f->allNeededIsKnown) error(toString(f) + ": undefined reference to " + toString(*sym)); - }); } // Now that we have defined all possible global symbols including linker- // synthesized ones. Visit all symbols to give the finishing touches. - symtab->forEachSymbol([](Symbol *sym) { + for (Symbol *sym : symtab->symbols()) { if (!includeInSymtab(*sym)) - return; + continue; if (in.symTab) in.symTab->addSymbol(sym); @@ -1791,7 +1789,7 @@ if (file->isNeeded && !sym->isUndefined()) addVerneed(sym); } - }); + } // We also need to scan the dynamic relocation tables of the other partitions // and add any referenced symbols to the partition's dynsym.