}
std::vector<Symbol *> 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);
// 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<CommonSymbol>(sym);
if (!s)
- return;
+ continue;
auto *bss = make<BssSection>("COMMON", s->size, s->alignment);
bss->file = s->file;
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
// 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<SharedSymbol>(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
// 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.
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;
// 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) {
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<SharedSymbol>(sym))
if (s->isUsedInRegularObj && !s->isWeak())
s->getFile().isNeeded = true;
- });
return;
}
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\"?";
// 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<std::vector<Symbol *>::const_iterator,
+ FilterOutPlaceholder>;
- void forEachSymbol(llvm::function_ref<void(Symbol *)> fn) {
- for (Symbol *sym : symVector)
- if (!sym->isPlaceholder())
- fn(sym);
+public:
+ llvm::iterator_range<iterator> 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);
// 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())
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.
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<SharedFile>(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);
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.