Index: ELF/Arch/MipsArchTree.cpp =================================================================== --- ELF/Arch/MipsArchTree.cpp +++ ELF/Arch/MipsArchTree.cpp @@ -283,7 +283,7 @@ template uint32_t elf::getMipsEFlags() { std::vector V; - for (ObjFile *F : ObjFile::Instances) + for (ObjFile *F : getInputFiles>()) V.push_back({F->getName(), F->getObj().getHeader()->e_flags}); if (V.empty()) return 0; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1031,11 +1031,11 @@ // Now that we have a complete list of input files. // Beyond this point, no new files are added. // Aggregate all input sections into one place. - for (ObjFile *F : ObjFile::Instances) + for (ObjFile *F : getInputFiles>()) for (InputSectionBase *S : F->getSections()) if (S && S != &InputSection::Discarded) InputSections.push_back(S); - for (BinaryFile *F : BinaryFile::Instances) + for (BinaryFile *F : getInputFiles()) for (InputSectionBase *S : F->getSections()) InputSections.push_back(cast(S)); Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -155,8 +155,6 @@ return F->kind() == Base::ObjectKind; } - static std::vector *> Instances; - ArrayRef getSymbols(); ArrayRef getLocalSymbols(); @@ -218,8 +216,6 @@ llvm::once_flag InitDwarfLine; }; -template std::vector *> ObjFile::Instances; - // LazyObjFile is analogous to ArchiveFile in the sense that // the file contains lazy symbols. The difference is that // LazyObjFile wraps a single file instead of multiple files. @@ -281,7 +277,6 @@ void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return Symbols; } std::unique_ptr Obj; - static std::vector Instances; private: std::vector Symbols; @@ -304,8 +299,6 @@ public: std::string SoName; - static std::vector *> Instances; - const Elf_Shdr *getSection(const Elf_Sym &Sym) const; llvm::ArrayRef getUndefinedSymbols() { return Undefs; } @@ -337,21 +330,27 @@ bool isNeeded() const { return !AsNeeded || IsUsed; } }; -template -std::vector *> SharedFile::Instances; - class BinaryFile : public InputFile { public: explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {} static bool classof(const InputFile *F) { return F->kind() == BinaryKind; } template void parse(); - static std::vector Instances; }; InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", uint64_t OffsetInArchive = 0); InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName); +extern std::vector InputFiles; + +template std::vector getInputFiles() { + std::vector Ret; + for (InputFile *F : InputFiles) + if (T *File = dyn_cast(F)) + Ret.push_back(File); + return Ret; +} + } // namespace elf } // namespace lld Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -35,6 +35,8 @@ using namespace lld; using namespace lld::elf; +std::vector elf::InputFiles; + TarWriter *elf::Tar; InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} @@ -826,8 +828,6 @@ } } -std::vector BitcodeFile::Instances; - BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, uint64_t OffsetInArchive) : InputFile(BitcodeKind, MB) { @@ -922,8 +922,6 @@ return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind; } -std::vector BinaryFile::Instances; - template void BinaryFile::parse() { ArrayRef Data = toArrayRef(MB.getBuffer()); auto *Section = Index: ELF/MapFile.cpp =================================================================== --- ELF/MapFile.cpp +++ ELF/MapFile.cpp @@ -51,7 +51,7 @@ // Returns a list of all symbols that we want to print out. template std::vector getSymbols() { std::vector V; - for (ObjFile *File : ObjFile::Instances) + for (ObjFile *File : getInputFiles>()) for (SymbolBody *B : File->getSymbols()) if (B->File == File && !B->isSection()) if (auto *Sym = dyn_cast(B)) Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -60,14 +60,7 @@ if (!isCompatible(File)) return; - // Binary file - if (auto *F = dyn_cast(File)) { - BinaryFile::Instances.push_back(F); - F->parse(); - return; - } - - // .a file + // .a file. if (auto *F = dyn_cast(File)) { F->parse(); return; @@ -88,22 +81,27 @@ F->parseSoName(); if (ErrorCount || !SoNames.insert(F->SoName).second) return; - SharedFile::Instances.push_back(F); + InputFiles.push_back(File); F->parseRest(); return; } - // LLVM bitcode file + InputFiles.push_back(File); + + // Binary file. + if (auto *F = dyn_cast(File)) { + F->parse(); + return; + } + + // LLVM bitcode file. if (auto *F = dyn_cast(File)) { - BitcodeFile::Instances.push_back(F); F->parse(ComdatGroups); return; } - // Regular object file - auto *F = cast>(File); - ObjFile::Instances.push_back(F); - F->parse(ComdatGroups); + // Regular object file. + cast>(File)->parse(ComdatGroups); } // This function is where all the optimizations of link-time @@ -114,19 +112,20 @@ // Because all bitcode files that consist of a program are passed // to the compiler at once, it can do whole-program optimization. template void SymbolTable::addCombinedLTOObject() { - if (BitcodeFile::Instances.empty()) + std::vector Files = getInputFiles(); + if (Files.empty()) return; // Compile bitcode files and replace bitcode symbols. LTO.reset(new BitcodeCompiler); - for (BitcodeFile *F : BitcodeFile::Instances) + for (BitcodeFile *F : Files) LTO->add(*F); for (InputFile *File : LTO->compile()) { ObjFile *Obj = cast>(File); DenseSet DummyGroups; Obj->parse(DummyGroups); - ObjFile::Instances.push_back(Obj); + InputFiles.push_back(Obj); } } @@ -598,7 +597,7 @@ // shared libraries can find them. // Except this, we ignore undefined symbols in DSOs. template void SymbolTable::scanShlibUndefined() { - for (SharedFile *File : SharedFile::Instances) { + for (SharedFile *File : getInputFiles>()) { for (StringRef U : File->getUndefinedSymbols()) { SymbolBody *Sym = find(U); if (!Sym || !Sym->isDefined()) Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1027,7 +1027,7 @@ if (!Config->Rpath.empty()) add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, InX::DynStrTab->addString(Config->Rpath)}); - for (SharedFile *F : SharedFile::Instances) + for (SharedFile *F : getInputFiles>()) if (F->isNeeded()) add({DT_NEEDED, InX::DynStrTab->addString(F->SoName)}); if (!Config->SoName.empty()) Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -116,7 +116,7 @@ } template static bool needsInterpSection() { - return !SharedFile::Instances.empty() && + return !getInputFiles>().empty() && !Config->DynamicLinker.empty() && !Script->ignoreInterpSection(); } @@ -305,8 +305,8 @@ Add(InX::BssRelRo); // Add MIPS-specific sections. - bool HasDynSymTab = !SharedFile::Instances.empty() || Config->Pic || - Config->ExportDynamic; + bool HasDynSymTab = !getInputFiles>().empty() || + Config->Pic || Config->ExportDynamic; if (Config->EMachine == EM_MIPS) { if (!Config->Shared && HasDynSymTab) { InX::MipsRldMap = make(); @@ -458,7 +458,7 @@ template void Writer::copyLocalSymbols() { if (!InX::SymTab) return; - for (ObjFile *F : ObjFile::Instances) { + for (ObjFile *F : getInputFiles>()) { for (SymbolBody *B : F->getLocalSymbols()) { if (!B->IsLocal) fatal(toString(F) + @@ -880,7 +880,7 @@ // Build a map from sections to their priorities. DenseMap SectionOrder; - for (ObjFile *File : ObjFile::Instances) { + for (ObjFile *File : getInputFiles>()) { for (SymbolBody *Body : File->getSymbols()) { auto *D = dyn_cast(Body); if (!D || !D->Section)