Index: lld/trunk/ELF/Arch/MipsArchTree.cpp =================================================================== --- lld/trunk/ELF/Arch/MipsArchTree.cpp +++ lld/trunk/ELF/Arch/MipsArchTree.cpp @@ -283,8 +283,9 @@ template uint32_t elf::getMipsEFlags() { std::vector V; - for (ObjFile *F : ObjFile::Instances) - V.push_back({F->getName(), F->getObj().getHeader()->e_flags}); + for (InputFile *F : ObjectFiles) + V.push_back( + {F->getName(), cast>(F)->getObj().getHeader()->e_flags}); if (V.empty()) return 0; checkFlags(V); Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -1015,8 +1015,8 @@ // producing a shared library. // We also need one if any shared libraries are used and for pie executables // (probably because the dynamic linker needs it). - Config->HasDynSymTab = !SharedFile::Instances.empty() || Config->Pic || - Config->ExportDynamic; + Config->HasDynSymTab = + !SharedFiles.empty() || Config->Pic || Config->ExportDynamic; // Some symbols (such as __ehdr_start) are defined lazily only when there // are undefined symbols for them, so we add these to trigger that logic. @@ -1064,11 +1064,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 (InputFile *F : ObjectFiles) for (InputSectionBase *S : F->getSections()) if (S && S != &InputSection::Discarded) InputSections.push_back(S); - for (BinaryFile *F : BinaryFile::Instances) + for (BinaryFile *F : BinaryFiles) for (InputSectionBase *S : F->getSections()) InputSections.push_back(cast(S)); Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -162,8 +162,6 @@ public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } - static std::vector *> Instances; - ArrayRef getLocalSymbols(); ObjFile(MemoryBufferRef M, StringRef ArchiveName); @@ -221,8 +219,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. @@ -279,7 +275,6 @@ template void parse(llvm::DenseSet &ComdatGroups); std::unique_ptr Obj; - static std::vector Instances; }; // .so file. @@ -299,8 +294,6 @@ public: std::string SoName; - static std::vector *> Instances; - const Elf_Shdr *getSection(const Elf_Sym &Sym) const; llvm::ArrayRef getUndefinedSymbols() { return Undefs; } @@ -332,21 +325,22 @@ 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 BinaryFiles; +extern std::vector BitcodeFiles; +extern std::vector ObjectFiles; +extern std::vector SharedFiles; + } // namespace elf } // namespace lld Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -35,6 +35,11 @@ using namespace lld; using namespace lld::elf; +std::vector elf::BinaryFiles; +std::vector elf::BitcodeFiles; +std::vector elf::ObjectFiles; +std::vector elf::SharedFiles; + TarWriter *elf::Tar; InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} @@ -820,8 +825,6 @@ } } -std::vector BitcodeFile::Instances; - BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, uint64_t OffsetInArchive) : InputFile(BitcodeKind, MB) { @@ -917,8 +920,6 @@ return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind; } -std::vector BinaryFile::Instances; - template void BinaryFile::parse() { ArrayRef Data = toArrayRef(MB.getBuffer()); auto *Section = Index: lld/trunk/ELF/InputSection.h =================================================================== --- lld/trunk/ELF/InputSection.h +++ lld/trunk/ELF/InputSection.h @@ -338,7 +338,7 @@ extern std::vector InputSections; // Builds section order for handling --symbol-ordering-file. -template llvm::DenseMap buildSectionOrder(); +llvm::DenseMap buildSectionOrder(); } // namespace elf Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -44,7 +44,7 @@ return (toString(Sec->File) + ":(" + Sec->Name + ")").str(); } -template DenseMap elf::buildSectionOrder() { +DenseMap elf::buildSectionOrder() { // Build a map from symbols to their priorities. Symbols that didn't // appear in the symbol ordering file have the lowest priority 0. // All explicitly mentioned symbols have negative (higher) priorities. @@ -55,7 +55,7 @@ // Build a map from sections to their priorities. DenseMap SectionOrder; - for (ObjFile *File : ObjFile::Instances) { + for (InputFile *File : ObjectFiles) { for (SymbolBody *Body : File->getSymbols()) { auto *D = dyn_cast(Body); if (!D || !D->Section) @@ -1001,11 +1001,6 @@ return Piece.OutputOff + Addend; } -template DenseMap elf::buildSectionOrder(); -template DenseMap elf::buildSectionOrder(); -template DenseMap elf::buildSectionOrder(); -template DenseMap elf::buildSectionOrder(); - template InputSection::InputSection(ObjFile *, const ELF32LE::Shdr *, StringRef); template InputSection::InputSection(ObjFile *, const ELF32BE::Shdr *, Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -241,25 +241,10 @@ std::stable_sort(Begin, End, getComparator(K)); } -static llvm::DenseMap getSectionOrder() { - switch (Config->EKind) { - case ELF32LEKind: - return buildSectionOrder(); - case ELF32BEKind: - return buildSectionOrder(); - case ELF64LEKind: - return buildSectionOrder(); - case ELF64BEKind: - return buildSectionOrder(); - default: - llvm_unreachable("unknown ELF type"); - } -} - static void sortBySymbolOrder(InputSection **Begin, InputSection **End) { if (Config->SymbolOrderingFile.empty()) return; - static llvm::DenseMap Order = getSectionOrder(); + static llvm::DenseMap Order = buildSectionOrder(); MutableArrayRef In(Begin, End - Begin); sortByOrder(In, [&](InputSectionBase *S) { return Order.lookup(S); }); } Index: lld/trunk/ELF/MapFile.cpp =================================================================== --- lld/trunk/ELF/MapFile.cpp +++ lld/trunk/ELF/MapFile.cpp @@ -50,7 +50,7 @@ // Returns a list of all symbols that we want to print out. template static std::vector getSymbols() { std::vector V; - for (ObjFile *File : ObjFile::Instances) { + for (InputFile *File : ObjectFiles) { for (SymbolBody *B : File->getSymbols()) { if (auto *DR = dyn_cast(B)) { if (DR->getFile() == File && !DR->isSection() && DR->Section && Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -62,7 +62,7 @@ // Binary file if (auto *F = dyn_cast(File)) { - BinaryFile::Instances.push_back(F); + BinaryFiles.push_back(F); F->parse(); return; } @@ -88,22 +88,21 @@ F->parseSoName(); if (ErrorCount || !SoNames.insert(F->SoName).second) return; - SharedFile::Instances.push_back(F); + SharedFiles.push_back(F); F->parseRest(); return; } // LLVM bitcode file if (auto *F = dyn_cast(File)) { - BitcodeFile::Instances.push_back(F); + BitcodeFiles.push_back(F); F->parse(ComdatGroups); return; } // Regular object file - auto *F = cast>(File); - ObjFile::Instances.push_back(F); - F->parse(ComdatGroups); + ObjectFiles.push_back(File); + cast>(File)->parse(ComdatGroups); } // This function is where all the optimizations of link-time @@ -114,19 +113,18 @@ // 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()) + if (BitcodeFiles.empty()) return; // Compile bitcode files and replace bitcode symbols. LTO.reset(new BitcodeCompiler); - for (BitcodeFile *F : BitcodeFile::Instances) + for (BitcodeFile *F : BitcodeFiles) LTO->add(*F); for (InputFile *File : LTO->compile()) { - ObjFile *Obj = cast>(File); DenseSet DummyGroups; - Obj->parse(DummyGroups); - ObjFile::Instances.push_back(Obj); + cast>(File)->parse(DummyGroups); + ObjectFiles.push_back(File); } } @@ -593,8 +591,8 @@ // shared libraries can find them. // Except this, we ignore undefined symbols in DSOs. template void SymbolTable::scanShlibUndefined() { - for (SharedFile *File : SharedFile::Instances) { - for (StringRef U : File->getUndefinedSymbols()) { + for (InputFile *F : SharedFiles) { + for (StringRef U : cast>(F)->getUndefinedSymbols()) { SymbolBody *Sym = find(U); if (!Sym || !Sym->isDefined()) continue; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1028,9 +1028,11 @@ if (!Config->Rpath.empty()) add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, InX::DynStrTab->addString(Config->Rpath)}); - for (SharedFile *F : SharedFile::Instances) + for (InputFile *File : SharedFiles) { + SharedFile *F = cast>(File); if (F->isNeeded()) add({DT_NEEDED, InX::DynStrTab->addString(F->SoName)}); + } if (!Config->SoName.empty()) add({DT_SONAME, InX::DynStrTab->addString(Config->SoName)}); Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -115,9 +115,9 @@ return Name; } -template static bool needsInterpSection() { - return !SharedFile::Instances.empty() && - !Config->DynamicLinker.empty() && !Script->ignoreInterpSection(); +static bool needsInterpSection() { + return !SharedFiles.empty() && !Config->DynamicLinker.empty() && + !Script->ignoreInterpSection(); } template void elf::writeResult() { Writer().run(); } @@ -273,7 +273,7 @@ Out::ProgramHeaders = make("", 0, SHF_ALLOC); Out::ProgramHeaders->updateAlignment(Config->Wordsize); - if (needsInterpSection()) { + if (needsInterpSection()) { InX::Interp = createInterpSection(); Add(InX::Interp); } else { @@ -454,7 +454,8 @@ template void Writer::copyLocalSymbols() { if (!InX::SymTab) return; - for (ObjFile *F : ObjFile::Instances) { + for (InputFile *File : ObjectFiles) { + ObjFile *F = cast>(File); for (SymbolBody *B : F->getLocalSymbols()) { if (!B->IsLocal) fatal(toString(F) + @@ -862,12 +863,12 @@ } // Sort input sections using the list provided by --symbol-ordering-file. -template static void sortBySymbolsOrder() { +static void sortBySymbolsOrder() { if (Config->SymbolOrderingFile.empty()) return; // Sort sections by priority. - DenseMap SectionOrder = buildSectionOrder(); + DenseMap SectionOrder = buildSectionOrder(); for (BaseCommand *Base : Script->Opt.Commands) if (auto *Sec = dyn_cast(Base)) Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); }); @@ -897,7 +898,7 @@ Old.end()); Script->fabricateDefaultCommands(); - sortBySymbolsOrder(); + sortBySymbolsOrder(); sortInitFini(findSection(".init_array")); sortInitFini(findSection(".fini_array")); sortCtorsDtors(findSection(".ctors"));