[lld] r286414 - Make OutputSectionBase a class instead of class template.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 9 15:23:47 PST 2016


Author: rafael
Date: Wed Nov  9 17:23:45 2016
New Revision: 286414

URL: http://llvm.org/viewvc/llvm-project?rev=286414&view=rev
Log:
Make OutputSectionBase a class instead of class template.

The disadvantage is that we use uint64_t instad of uint32_t for some
value in 32 bit files. The advantage is a substantially simpler code,
faster builds and less code duplication.

Modified:
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/ELF/Writer.h

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Wed Nov  9 17:23:45 2016
@@ -29,7 +29,7 @@ template <class ELFT> class ICF;
 template <class ELFT> class DefinedRegular;
 template <class ELFT> class ObjectFile;
 template <class ELFT> class OutputSection;
-template <class ELFT> class OutputSectionBase;
+class OutputSectionBase;
 
 // We need non-template input section class to store symbol layout
 // in linker script parser structures, where we do not have ELFT
@@ -104,7 +104,7 @@ public:
                    uintX_t Entsize, uint32_t Link, uint32_t Info,
                    uintX_t Addralign, ArrayRef<uint8_t> Data, StringRef Name,
                    Kind SectionKind);
-  OutputSectionBase<ELFT> *OutSec = nullptr;
+  OutputSectionBase *OutSec = nullptr;
 
   // This pointer points to the "real" instance of this instance.
   // Usually Repl == this. However, if ICF merges two sections,

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Nov  9 17:23:45 2016
@@ -229,7 +229,7 @@ void LinkerScript<ELFT>::computeInputSec
   // section for now.
   for (InputSectionData *S : I->Sections) {
     auto *S2 = static_cast<InputSectionBase<ELFT> *>(S);
-    S2->OutSec = (OutputSectionBase<ELFT> *)-1;
+    S2->OutSec = (OutputSectionBase *)-1;
   }
 }
 
@@ -298,7 +298,7 @@ template <class ELFT>
 void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
                                     InputSectionBase<ELFT> *Sec,
                                     StringRef Name) {
-  OutputSectionBase<ELFT> *OutSec;
+  OutputSectionBase *OutSec;
   bool IsNew;
   std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
   if (IsNew)
@@ -373,8 +373,7 @@ void LinkerScript<ELFT>::createSections(
 // is an offset from beginning of section and regular
 // symbols whose value is absolute.
 template <class ELFT>
-static void assignSectionSymbol(SymbolAssignment *Cmd,
-                                OutputSectionBase<ELFT> *Sec,
+static void assignSectionSymbol(SymbolAssignment *Cmd, OutputSectionBase *Sec,
                                 typename ELFT::uint Value) {
   if (!Cmd->Sym)
     return;
@@ -388,14 +387,14 @@ static void assignSectionSymbol(SymbolAs
   Body->Value = Cmd->Expression(Value);
 }
 
-template <class ELFT> static bool isTbss(OutputSectionBase<ELFT> *Sec) {
+template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
   return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
 }
 
 template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) {
   if (!AlreadyOutputIS.insert(S).second)
     return;
-  bool IsTbss = isTbss(CurOutSec);
+  bool IsTbss = isTbss<ELFT>(CurOutSec);
 
   uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
   Pos = alignTo(Pos, S->Alignment);
@@ -425,7 +424,7 @@ template <class ELFT> void LinkerScript<
 }
 
 template <class ELFT>
-void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) {
+void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) {
   if (CurOutSec == Sec)
     return;
   if (AlreadyOutputOS.count(Sec))
@@ -435,7 +434,7 @@ void LinkerScript<ELFT>::switchTo(Output
   CurOutSec = Sec;
 
   Dot = alignTo(Dot, CurOutSec->Addralign);
-  CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot;
+  CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset : Dot;
 
   // If neither AT nor AT> is specified for an allocatable section, the linker
   // will set the LMA such that the difference between VMA and LMA for the
@@ -480,11 +479,10 @@ template <class ELFT> void LinkerScript<
 }
 
 template <class ELFT>
-static std::vector<OutputSectionBase<ELFT> *>
-findSections(StringRef Name,
-             const std::vector<OutputSectionBase<ELFT> *> &Sections) {
-  std::vector<OutputSectionBase<ELFT> *> Ret;
-  for (OutputSectionBase<ELFT> *Sec : Sections)
+static std::vector<OutputSectionBase *>
+findSections(StringRef Name, const std::vector<OutputSectionBase *> &Sections) {
+  std::vector<OutputSectionBase *> Ret;
+  for (OutputSectionBase *Sec : Sections)
     if (Sec->getName() == Name)
       Ret.push_back(Sec);
   return Ret;
@@ -494,8 +492,8 @@ template <class ELFT>
 void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
   if (Cmd->LMAExpr)
     LMAOffset = Cmd->LMAExpr(Dot) - Dot;
-  std::vector<OutputSectionBase<ELFT> *> Sections =
-      findSections(Cmd->Name, *OutputSections);
+  std::vector<OutputSectionBase *> Sections =
+      findSections<ELFT>(Cmd->Name, *OutputSections);
   if (Sections.empty())
     return;
   switchTo(Sections[0]);
@@ -508,7 +506,7 @@ void LinkerScript<ELFT>::assignOffsets(O
                .base();
   for (auto I = Cmd->Commands.begin(); I != E; ++I)
     process(**I);
-  for (OutputSectionBase<ELFT> *Base : Sections)
+  for (OutputSectionBase *Base : Sections)
     switchTo(Base);
   flush();
   std::for_each(E, Cmd->Commands.end(),
@@ -528,8 +526,8 @@ template <class ELFT> void LinkerScript<
         auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
         if (!Cmd)
           return false;
-        std::vector<OutputSectionBase<ELFT> *> Secs =
-            findSections(Cmd->Name, *OutputSections);
+        std::vector<OutputSectionBase *> Secs =
+            findSections<ELFT>(Cmd->Name, *OutputSections);
         if (!Secs.empty())
           return false;
         for (const std::unique_ptr<BaseCommand> &I : Cmd->Commands)
@@ -549,8 +547,8 @@ template <class ELFT> void LinkerScript<
     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
     if (!Cmd)
       continue;
-    std::vector<OutputSectionBase<ELFT> *> Secs =
-        findSections(Cmd->Name, *OutputSections);
+    std::vector<OutputSectionBase *> Secs =
+        findSections<ELFT>(Cmd->Name, *OutputSections);
     if (!Secs.empty()) {
       Flags = Secs[0]->Flags;
       Type = Secs[0]->Type;
@@ -597,7 +595,7 @@ void LinkerScript<ELFT>::assignAddresses
   // This loops creates or moves commands as needed so that they are in the
   // correct order.
   int CmdIndex = 0;
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
+  for (OutputSectionBase *Sec : *OutputSections) {
     StringRef Name = Sec->getName();
 
     // Find the last spot where we can insert a command and still get the
@@ -633,8 +631,8 @@ void LinkerScript<ELFT>::assignAddresses
       if (Cmd->Name == ".") {
         Dot = Cmd->Expression(Dot);
       } else if (Cmd->Sym) {
-        assignSectionSymbol(Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0],
-                            Dot);
+        assignSectionSymbol<ELFT>(
+            Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], Dot);
       }
       continue;
     }
@@ -653,9 +651,9 @@ void LinkerScript<ELFT>::assignAddresses
   }
 
   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
+  for (OutputSectionBase *Sec : *OutputSections) {
     if (Sec->Flags & SHF_ALLOC)
-      MinVA = std::min(MinVA, Sec->Addr);
+      MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
     else
       Sec->Addr = 0;
   }
@@ -730,7 +728,7 @@ std::vector<PhdrEntry<ELFT>> LinkerScrip
   }
 
   // Add output sections to program headers.
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
+  for (OutputSectionBase *Sec : *OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
 
@@ -831,7 +829,7 @@ template <class ELFT> bool LinkerScript<
 
 template <class ELFT>
 uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) {
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
+  for (OutputSectionBase *Sec : *OutputSections)
     if (Sec->getName() == Name)
       return Sec->Addr;
   error("undefined section " + Name);
@@ -840,7 +838,7 @@ uint64_t LinkerScript<ELFT>::getOutputSe
 
 template <class ELFT>
 uint64_t LinkerScript<ELFT>::getOutputSectionLMA(StringRef Name) {
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
+  for (OutputSectionBase *Sec : *OutputSections)
     if (Sec->getName() == Name)
       return Sec->getLMA();
   error("undefined section " + Name);
@@ -849,7 +847,7 @@ uint64_t LinkerScript<ELFT>::getOutputSe
 
 template <class ELFT>
 uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
+  for (OutputSectionBase *Sec : *OutputSections)
     if (Sec->getName() == Name)
       return Sec->Size;
   error("undefined section " + Name);
@@ -858,7 +856,7 @@ uint64_t LinkerScript<ELFT>::getOutputSe
 
 template <class ELFT>
 uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) {
-  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
+  for (OutputSectionBase *Sec : *OutputSections)
     if (Sec->getName() == Name)
       return Sec->Addralign;
   error("undefined section " + Name);

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Nov  9 17:23:45 2016
@@ -32,7 +32,7 @@ class ScriptParser;
 class SymbolBody;
 template <class ELFT> class InputSectionBase;
 template <class ELFT> class InputSection;
-template <class ELFT> class OutputSectionBase;
+class OutputSectionBase;
 template <class ELFT> class OutputSectionFactory;
 class InputSectionData;
 
@@ -240,7 +240,7 @@ public:
   bool isDefined(StringRef S) override;
   bool isAbsolute(StringRef S) override;
 
-  std::vector<OutputSectionBase<ELFT> *> *OutputSections;
+  std::vector<OutputSectionBase *> *OutputSections;
 
   int getSectionIndex(StringRef Name);
 
@@ -262,13 +262,13 @@ private:
 
   uintX_t Dot;
   uintX_t LMAOffset = 0;
-  OutputSectionBase<ELFT> *CurOutSec = nullptr;
+  OutputSectionBase *CurOutSec = nullptr;
   uintX_t ThreadBssOffset = 0;
-  void switchTo(OutputSectionBase<ELFT> *Sec);
+  void switchTo(OutputSectionBase *Sec);
   void flush();
   void output(InputSection<ELFT> *Sec);
   void process(BaseCommand &Base);
-  llvm::DenseSet<OutputSectionBase<ELFT> *> AlreadyOutputOS;
+  llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS;
   llvm::DenseSet<InputSectionData *> AlreadyOutputIS;
 };
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Nov  9 17:23:45 2016
@@ -32,16 +32,15 @@ using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf;
 
-template <class ELFT>
-OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t Type,
-                                           uintX_t Flags)
+OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type,
+                                     uint64_t Flags)
     : Name(Name) {
   this->Type = Type;
   this->Flags = Flags;
   this->Addralign = 1;
 }
 
-template <class ELFT> uint32_t OutputSectionBase<ELFT>::getPhdrFlags() const {
+uint32_t OutputSectionBase::getPhdrFlags() const {
   uint32_t Ret = PF_R;
   if (Flags & SHF_WRITE)
     Ret |= PF_W;
@@ -51,7 +50,7 @@ template <class ELFT> uint32_t OutputSec
 }
 
 template <class ELFT>
-void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *Shdr) {
+void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) {
   Shdr->sh_entsize = Entsize;
   Shdr->sh_addralign = Addralign;
   Shdr->sh_type = Type;
@@ -66,7 +65,7 @@ void OutputSectionBase<ELFT>::writeHeade
 
 template <class ELFT>
 GdbIndexSection<ELFT>::GdbIndexSection()
-    : OutputSectionBase<ELFT>(".gdb_index", SHT_PROGBITS, 0) {}
+    : OutputSectionBase(".gdb_index", SHT_PROGBITS, 0) {}
 
 template <class ELFT> void GdbIndexSection<ELFT>::parseDebugSections() {
   std::vector<InputSection<ELFT> *> &IS =
@@ -110,7 +109,7 @@ template <class ELFT> void GdbIndexSecti
 
 template <class ELFT>
 GotPltSection<ELFT>::GotPltSection()
-    : OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
+    : OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
   this->Addralign = Target->GotPltEntrySize;
 }
 
@@ -139,7 +138,7 @@ template <class ELFT> void GotPltSection
 
 template <class ELFT>
 GotSection<ELFT>::GotSection()
-    : OutputSectionBase<ELFT>(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
+    : OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
   if (Config->EMachine == EM_MIPS)
     this->Flags |= SHF_MIPS_GPREL;
   this->Addralign = Target->GotEntrySize;
@@ -313,7 +312,7 @@ template <class ELFT> void GotSection<EL
     // Take into account MIPS GOT header.
     // See comment in the GotSection::writeTo.
     MipsPageEntries += 2;
-    for (const OutputSectionBase<ELFT> *OutSec : MipsOutSections) {
+    for (const OutputSectionBase *OutSec : MipsOutSections) {
       // Calculate an upper bound of MIPS GOT entries required to store page
       // addresses of local symbols. We assume the worst case - each 64kb
       // page of the output section has at least one GOT relocation against it.
@@ -408,7 +407,7 @@ template <class ELFT> void GotSection<EL
 
 template <class ELFT>
 PltSection<ELFT>::PltSection()
-    : OutputSectionBase<ELFT>(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
+    : OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
   this->Addralign = 16;
 }
 
@@ -440,8 +439,7 @@ template <class ELFT> void PltSection<EL
 
 template <class ELFT>
 RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
-    : OutputSectionBase<ELFT>(Name, Config->Rela ? SHT_RELA : SHT_REL,
-                              SHF_ALLOC),
+    : OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, SHF_ALLOC),
       Sort(Sort) {
   this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
   this->Addralign = sizeof(uintX_t);
@@ -504,7 +502,7 @@ template <class ELFT> void RelocationSec
 
 template <class ELFT>
 HashTableSection<ELFT>::HashTableSection()
-    : OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) {
+    : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) {
   this->Entsize = sizeof(Elf_Word);
   this->Addralign = sizeof(Elf_Word);
 }
@@ -550,7 +548,7 @@ static uint32_t hashGnu(StringRef Name)
 
 template <class ELFT>
 GnuHashTableSection<ELFT>::GnuHashTableSection()
-    : OutputSectionBase<ELFT>(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
+    : OutputSectionBase(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
   this->Entsize = ELFT::Is64Bits ? 0 : 4;
   this->Addralign = sizeof(uintX_t);
 }
@@ -695,7 +693,7 @@ static unsigned getVerDefNum() { return
 
 template <class ELFT>
 DynamicSection<ELFT>::DynamicSection()
-    : OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) {
+    : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) {
   this->Addralign = sizeof(uintX_t);
   this->Entsize = ELFT::Is64Bits ? 16 : 8;
 
@@ -863,7 +861,7 @@ template <class ELFT> void DynamicSectio
 
 template <class ELFT>
 EhFrameHeader<ELFT>::EhFrameHeader()
-    : OutputSectionBase<ELFT>(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
+    : OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
 
 // .eh_frame_hdr contains a binary search table of pointers to FDEs.
 // Each entry of the search table consists of two values,
@@ -925,7 +923,7 @@ template <class ELFT> static uint64_t ge
 
 template <class ELFT>
 OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags)
-    : OutputSectionBase<ELFT>(Name, Type, Flags) {
+    : OutputSectionBase(Name, Type, Flags) {
   this->Entsize = getEntsize<ELFT>(Type);
 }
 
@@ -956,7 +954,7 @@ template <class ELFT> void OutputSection
 }
 
 template <class ELFT>
-void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
+void OutputSection<ELFT>::addSection(InputSectionData *C) {
   assert(C->Live);
   auto *S = cast<InputSection<ELFT>>(C);
   Sections.push_back(S);
@@ -1085,7 +1083,7 @@ template <class ELFT> void OutputSection
 
 template <class ELFT>
 EhOutputSection<ELFT>::EhOutputSection()
-    : OutputSectionBase<ELFT>(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
+    : OutputSectionBase(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
 
 // Search for an existing CIE record or create a new one.
 // CIE records from input object files are uniquified by their contents
@@ -1170,7 +1168,7 @@ void EhOutputSection<ELFT>::addSectionAu
 }
 
 template <class ELFT>
-void EhOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
+void EhOutputSection<ELFT>::addSection(InputSectionData *C) {
   auto *Sec = cast<EhInputSection<ELFT>>(C);
   Sec->OutSec = this;
   this->updateAlignment(Sec->Alignment);
@@ -1290,7 +1288,7 @@ template <class ELFT> void EhOutputSecti
 template <class ELFT>
 MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t Type,
                                              uintX_t Flags, uintX_t Alignment)
-    : OutputSectionBase<ELFT>(Name, Type, Flags),
+    : OutputSectionBase(Name, Type, Flags),
       Builder(StringTableBuilder::RAW, Alignment) {}
 
 template <class ELFT> void MergeOutputSection<ELFT>::writeTo(uint8_t *Buf) {
@@ -1298,7 +1296,7 @@ template <class ELFT> void MergeOutputSe
 }
 
 template <class ELFT>
-void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
+void MergeOutputSection<ELFT>::addSection(InputSectionData *C) {
   auto *Sec = cast<MergeInputSection<ELFT>>(C);
   Sec->OutSec = this;
   this->updateAlignment(Sec->Alignment);
@@ -1344,8 +1342,7 @@ template <class ELFT> void MergeOutputSe
 
 template <class ELFT>
 StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
-    : OutputSectionBase<ELFT>(Name, SHT_STRTAB,
-                              Dynamic ? (uintX_t)SHF_ALLOC : 0),
+    : OutputSectionBase(Name, SHT_STRTAB, Dynamic ? (uintX_t)SHF_ALLOC : 0),
       Dynamic(Dynamic) {
   // ELF string tables start with a NUL byte, so 1.
   this->Size = 1;
@@ -1400,9 +1397,9 @@ template <class ELFT> uint32_t DynamicRe
 template <class ELFT>
 SymbolTableSection<ELFT>::SymbolTableSection(
     StringTableSection<ELFT> &StrTabSec)
-    : OutputSectionBase<ELFT>(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
-                              StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
-                              StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0),
+    : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
+                        StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
+                        StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0),
       StrTabSec(StrTabSec) {
   this->Entsize = sizeof(Elf_Sym);
   this->Addralign = sizeof(uintX_t);
@@ -1501,7 +1498,7 @@ void SymbolTableSection<ELFT>::writeLoca
         ESym->st_shndx = SHN_ABS;
         ESym->st_value = Body.Value;
       } else {
-        const OutputSectionBase<ELFT> *OutSec = Section->OutSec;
+        const OutputSectionBase *OutSec = Section->OutSec;
         ESym->st_shndx = OutSec->SectionIndex;
         ESym->st_value = OutSec->Addr + Section->getOffset(Body);
       }
@@ -1531,7 +1528,7 @@ void SymbolTableSection<ELFT>::writeGlob
     ESym->setVisibility(Body->symbol()->Visibility);
     ESym->st_value = Body->getVA<ELFT>();
 
-    if (const OutputSectionBase<ELFT> *OutSec = getOutputSection(Body))
+    if (const OutputSectionBase *OutSec = getOutputSection(Body))
       ESym->st_shndx = OutSec->SectionIndex;
     else if (isa<DefinedRegular<ELFT>>(Body))
       ESym->st_shndx = SHN_ABS;
@@ -1554,7 +1551,7 @@ void SymbolTableSection<ELFT>::writeGlob
 }
 
 template <class ELFT>
-const OutputSectionBase<ELFT> *
+const OutputSectionBase *
 SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
   switch (Sym->kind()) {
   case SymbolBody::DefinedSyntheticKind:
@@ -1581,7 +1578,7 @@ SymbolTableSection<ELFT>::getOutputSecti
 
 template <class ELFT>
 VersionDefinitionSection<ELFT>::VersionDefinitionSection()
-    : OutputSectionBase<ELFT>(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) {
+    : OutputSectionBase(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) {
   this->Addralign = sizeof(uint32_t);
 }
 
@@ -1638,7 +1635,7 @@ void VersionDefinitionSection<ELFT>::wri
 
 template <class ELFT>
 VersionTableSection<ELFT>::VersionTableSection()
-    : OutputSectionBase<ELFT>(".gnu.version", SHT_GNU_versym, SHF_ALLOC) {
+    : OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) {
   this->Addralign = sizeof(uint16_t);
 }
 
@@ -1661,7 +1658,7 @@ template <class ELFT> void VersionTableS
 
 template <class ELFT>
 VersionNeedSection<ELFT>::VersionNeedSection()
-    : OutputSectionBase<ELFT>(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) {
+    : OutputSectionBase(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) {
   this->Addralign = sizeof(uint32_t);
 
   // Identifiers in verneed section start at 2 because 0 and 1 are reserved
@@ -1764,7 +1761,7 @@ static SectionKey<ELFT::Is64Bits> create
 }
 
 template <class ELFT>
-std::pair<OutputSectionBase<ELFT> *, bool>
+std::pair<OutputSectionBase *, bool>
 OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
                                    StringRef OutsecName) {
   SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
@@ -1772,11 +1769,11 @@ OutputSectionFactory<ELFT>::create(Input
 }
 
 template <class ELFT>
-std::pair<OutputSectionBase<ELFT> *, bool>
+std::pair<OutputSectionBase *, bool>
 OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key,
                                    InputSectionBase<ELFT> *C) {
   uintX_t Flags = getOutFlags(C);
-  OutputSectionBase<ELFT> *&Sec = Map[Key];
+  OutputSectionBase *&Sec = Map[Key];
   if (Sec) {
     Sec->Flags |= Flags;
     return {Sec, false};
@@ -1830,10 +1827,11 @@ template struct DenseMapInfo<SectionKey<
 
 namespace lld {
 namespace elf {
-template class OutputSectionBase<ELF32LE>;
-template class OutputSectionBase<ELF32BE>;
-template class OutputSectionBase<ELF64LE>;
-template class OutputSectionBase<ELF64BE>;
+
+template void OutputSectionBase::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
+template void OutputSectionBase::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
+template void OutputSectionBase::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
+template void OutputSectionBase::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
 
 template class EhFrameHeader<ELF32LE>;
 template class EhFrameHeader<ELF32BE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Nov  9 17:23:45 2016
@@ -42,10 +42,8 @@ template <class ELFT> class DefinedRegul
 // input sections, others are created by the linker.
 // The writer creates multiple OutputSections and assign them unique,
 // non-overlapping file offsets and VAs.
-template <class ELFT> class OutputSectionBase {
+class OutputSectionBase {
 public:
-  typedef typename ELFT::uint uintX_t;
-  typedef typename ELFT::Shdr Elf_Shdr;
   enum Kind {
     Base,
     Dynamic,
@@ -66,15 +64,15 @@ public:
     VersTable
   };
 
-  OutputSectionBase(StringRef Name, uint32_t Type, uintX_t Flags);
-  void setLMAOffset(uintX_t LMAOff) { LMAOffset = LMAOff; }
-  uintX_t getLMA() const { return Addr + LMAOffset; }
-  void writeHeaderTo(Elf_Shdr *SHdr);
+  OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags);
+  void setLMAOffset(uint64_t LMAOff) { LMAOffset = LMAOff; }
+  uint64_t getLMA() const { return Addr + LMAOffset; }
+  template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
   StringRef getName() const { return Name; }
 
-  virtual void addSection(InputSectionBase<ELFT> *C) {}
+  virtual void addSection(InputSectionData *C) {}
   virtual Kind getKind() const { return Base; }
-  static bool classof(const OutputSectionBase<ELFT> *B) {
+  static bool classof(const OutputSectionBase *B) {
     return B->getKind() == Base;
   }
 
@@ -82,7 +80,7 @@ public:
 
   uint32_t getPhdrFlags() const;
 
-  void updateAlignment(uintX_t Alignment) {
+  void updateAlignment(uint64_t Alignment) {
     if (Alignment > Addralign)
       Addralign = Alignment;
   }
@@ -97,7 +95,7 @@ public:
   // between their file offsets should be equal to difference between their
   // virtual addresses. To compute some section offset we use the following
   // formula: Off = Off_first + VA - VA_first.
-  OutputSectionBase<ELFT> *FirstInPtLoad = nullptr;
+  OutputSectionBase *FirstInPtLoad = nullptr;
 
   virtual void finalize() {}
   virtual void finalizePieces() {}
@@ -108,21 +106,20 @@ public:
   StringRef Name;
 
   // The following fields correspond to Elf_Shdr members.
-  uintX_t Size = 0;
-  uintX_t Entsize = 0;
-  uintX_t Addralign = 0;
-  uintX_t Offset = 0;
-  uintX_t Flags = 0;
-  uintX_t LMAOffset = 0;
-  uintX_t Addr = 0;
+  uint64_t Size = 0;
+  uint64_t Entsize = 0;
+  uint64_t Addralign = 0;
+  uint64_t Offset = 0;
+  uint64_t Flags = 0;
+  uint64_t LMAOffset = 0;
+  uint64_t Addr = 0;
   uint32_t ShName = 0;
   uint32_t Type = 0;
   uint32_t Info = 0;
   uint32_t Link = 0;
 };
 
-template <class ELFT>
-class GdbIndexSection final : public OutputSectionBase<ELFT> {
+template <class ELFT> class GdbIndexSection final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
 
   const unsigned OffsetTypeSize = 4;
@@ -146,8 +143,7 @@ private:
   uint32_t CuTypesOffset;
 };
 
-template <class ELFT> class GotSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+template <class ELFT> class GotSection final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
 
 public:
@@ -163,8 +159,10 @@ public:
   uintX_t getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const;
   uintX_t getGlobalDynAddr(const SymbolBody &B) const;
   uintX_t getGlobalDynOffset(const SymbolBody &B) const;
-  typename Base::Kind getKind() const override { return Base::Got; }
-  static bool classof(const Base *B) { return B->getKind() == Base::Got; }
+  Kind getKind() const override { return Got; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == Got;
+  }
 
   // Returns the symbol which corresponds to the first entry of the global part
   // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
@@ -192,7 +190,7 @@ private:
   uint32_t TlsIndexOff = -1;
   uint32_t MipsPageEntries = 0;
   // Output sections referenced by MIPS GOT relocations.
-  llvm::SmallPtrSet<const OutputSectionBase<ELFT> *, 10> MipsOutSections;
+  llvm::SmallPtrSet<const OutputSectionBase *, 10> MipsOutSections;
   llvm::DenseMap<uintX_t, size_t> MipsLocalGotPos;
 
   // MIPS ABI requires to create unique GOT entry for each Symbol/Addend
@@ -213,10 +211,8 @@ private:
   void writeMipsGot(uint8_t *Buf);
 };
 
-template <class ELFT>
-class GotPltSection final : public OutputSectionBase<ELFT> {
+template <class ELFT> class GotPltSection final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   GotPltSection();
@@ -224,15 +220,16 @@ public:
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody &Sym);
   bool empty() const;
-  typename Base::Kind getKind() const override { return Base::GotPlt; }
-  static bool classof(const Base *B) { return B->getKind() == Base::GotPlt; }
+  Kind getKind() const override { return GotPlt; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == GotPlt;
+  }
 
 private:
   std::vector<const SymbolBody *> Entries;
 };
 
-template <class ELFT> class PltSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+template <class ELFT> class PltSection final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
 
 public:
@@ -241,8 +238,10 @@ public:
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody &Sym);
   bool empty() const { return Entries.empty(); }
-  typename Base::Kind getKind() const override { return Base::Plt; }
-  static bool classof(const Base *B) { return B->getKind() == Base::Plt; }
+  Kind getKind() const override { return Plt; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == Plt;
+  }
 
 private:
   std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
@@ -258,7 +257,7 @@ public:
       : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
         UseSymVA(UseSymVA), Addend(Addend) {}
 
-  DynamicReloc(uint32_t Type, const OutputSectionBase<ELFT> *OutputSec,
+  DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
                uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
                uintX_t Addend)
       : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
@@ -267,14 +266,14 @@ public:
   uintX_t getOffset() const;
   uintX_t getAddend() const;
   uint32_t getSymIndex() const;
-  const OutputSectionBase<ELFT> *getOutputSec() const { return OutputSec; }
+  const OutputSectionBase *getOutputSec() const { return OutputSec; }
 
   uint32_t Type;
 
 private:
   SymbolBody *Sym;
   const InputSectionBase<ELFT> *InputSec = nullptr;
-  const OutputSectionBase<ELFT> *OutputSec = nullptr;
+  const OutputSectionBase *OutputSec = nullptr;
   uintX_t OffsetInSec;
   bool UseSymVA;
   uintX_t Addend;
@@ -286,8 +285,8 @@ struct SymbolTableEntry {
 };
 
 template <class ELFT>
-class SymbolTableSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+class SymbolTableSection final : public OutputSectionBase {
+  typedef OutputSectionBase Base;
 
 public:
   typedef typename ELFT::Shdr Elf_Shdr;
@@ -313,7 +312,7 @@ private:
   void writeLocalSymbols(uint8_t *&Buf);
   void writeGlobalSymbols(uint8_t *Buf);
 
-  const OutputSectionBase<ELFT> *getOutputSection(SymbolBody *Sym);
+  const OutputSectionBase *getOutputSection(SymbolBody *Sym);
 
   // A vector of symbols and their string table offsets.
   std::vector<SymbolTableEntry> Symbols;
@@ -328,17 +327,18 @@ private:
 // The section shall contain an array of Elf_Verdef structures, optionally
 // followed by an array of Elf_Verdaux structures.
 template <class ELFT>
-class VersionDefinitionSection final : public OutputSectionBase<ELFT> {
+class VersionDefinitionSection final : public OutputSectionBase {
   typedef typename ELFT::Verdef Elf_Verdef;
   typedef typename ELFT::Verdaux Elf_Verdaux;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   VersionDefinitionSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  typename Base::Kind getKind() const override { return Base::VersDef; }
-  static bool classof(const Base *B) { return B->getKind() == Base::VersDef; }
+  Kind getKind() const override { return VersDef; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == VersDef;
+  }
 
 private:
   void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
@@ -353,16 +353,17 @@ private:
 // The values 0 and 1 are reserved. All other values are used for versions in
 // the own object or in any of the dependencies.
 template <class ELFT>
-class VersionTableSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+class VersionTableSection final : public OutputSectionBase {
   typedef typename ELFT::Versym Elf_Versym;
 
 public:
   VersionTableSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  typename Base::Kind getKind() const override { return Base::VersTable; }
-  static bool classof(const Base *B) { return B->getKind() == Base::VersTable; }
+  Kind getKind() const override { return VersTable; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == VersTable;
+  }
 };
 
 // The .gnu.version_r section defines the version identifiers used by
@@ -371,8 +372,7 @@ public:
 // a reference to a linked list of Elf_Vernaux data structures which define the
 // mapping from version identifiers to version names.
 template <class ELFT>
-class VersionNeedSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+class VersionNeedSection final : public OutputSectionBase {
   typedef typename ELFT::Verneed Elf_Verneed;
   typedef typename ELFT::Vernaux Elf_Vernaux;
 
@@ -389,16 +389,16 @@ public:
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   size_t getNeedNum() const { return Needed.size(); }
-  typename Base::Kind getKind() const override { return Base::VersNeed; }
-  static bool classof(const Base *B) { return B->getKind() == Base::VersNeed; }
+  Kind getKind() const override { return VersNeed; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == VersNeed;
+  }
 };
 
-template <class ELFT>
-class RelocationSection final : public OutputSectionBase<ELFT> {
+template <class ELFT> class RelocationSection final : public OutputSectionBase {
   typedef typename ELFT::Rel Elf_Rel;
   typedef typename ELFT::Rela Elf_Rela;
   typedef typename ELFT::uint uintX_t;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   RelocationSection(StringRef Name, bool Sort);
@@ -407,9 +407,11 @@ public:
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   bool hasRelocs() const { return !Relocs.empty(); }
-  typename Base::Kind getKind() const override { return Base::Reloc; }
+  Kind getKind() const override { return Reloc; }
   size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
-  static bool classof(const Base *B) { return B->getKind() == Base::Reloc; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == Reloc;
+  }
 
 private:
   bool Sort;
@@ -417,9 +419,7 @@ private:
   std::vector<DynamicReloc<ELFT>> Relocs;
 };
 
-template <class ELFT>
-class OutputSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+template <class ELFT> class OutputSection final : public OutputSectionBase {
 
 public:
   typedef typename ELFT::Shdr Elf_Shdr;
@@ -428,33 +428,36 @@ public:
   typedef typename ELFT::Rela Elf_Rela;
   typedef typename ELFT::uint uintX_t;
   OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
-  void addSection(InputSectionBase<ELFT> *C) override;
+  void addSection(InputSectionData *C) override;
   void sortInitFini();
   void sortCtorsDtors();
   void writeTo(uint8_t *Buf) override;
   void finalize() override;
   void assignOffsets() override;
-  typename Base::Kind getKind() const override { return Base::Regular; }
-  static bool classof(const Base *B) { return B->getKind() == Base::Regular; }
+  Kind getKind() const override { return Regular; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == Regular;
+  }
   std::vector<InputSection<ELFT> *> Sections;
 };
 
 template <class ELFT>
-class MergeOutputSection final : public OutputSectionBase<ELFT> {
+class MergeOutputSection final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags,
                      uintX_t Alignment);
-  void addSection(InputSectionBase<ELFT> *S) override;
+  void addSection(InputSectionData *S) override;
   void writeTo(uint8_t *Buf) override;
   unsigned getOffset(llvm::CachedHashStringRef Val);
   void finalize() override;
   void finalizePieces() override;
   bool shouldTailMerge() const;
-  typename Base::Kind getKind() const override { return Base::Merge; }
-  static bool classof(const Base *B) { return B->getKind() == Base::Merge; }
+  Kind getKind() const override { return Merge; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == Merge;
+  }
 
 private:
   llvm::StringTableBuilder Builder;
@@ -467,13 +470,11 @@ struct CieRecord {
 };
 
 // Output section for .eh_frame.
-template <class ELFT>
-class EhOutputSection final : public OutputSectionBase<ELFT> {
+template <class ELFT> class EhOutputSection final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
   typedef typename ELFT::Shdr Elf_Shdr;
   typedef typename ELFT::Rel Elf_Rel;
   typedef typename ELFT::Rela Elf_Rela;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   EhOutputSection();
@@ -481,9 +482,11 @@ public:
   void finalize() override;
   bool empty() const { return Sections.empty(); }
 
-  void addSection(InputSectionBase<ELFT> *S) override;
-  typename Base::Kind getKind() const override { return Base::EHFrame; }
-  static bool classof(const Base *B) { return B->getKind() == Base::EHFrame; }
+  void addSection(InputSectionData *S) override;
+  Kind getKind() const override { return EHFrame; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == EHFrame;
+  }
 
   size_t NumFdes = 0;
 
@@ -509,8 +512,7 @@ private:
 };
 
 template <class ELFT>
-class StringTableSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+class StringTableSection final : public OutputSectionBase {
 
 public:
   typedef typename ELFT::uint uintX_t;
@@ -518,8 +520,10 @@ public:
   unsigned addString(StringRef S, bool HashIt = true);
   void writeTo(uint8_t *Buf) override;
   bool isDynamic() const { return Dynamic; }
-  typename Base::Kind getKind() const override { return Base::StrTable; }
-  static bool classof(const Base *B) { return B->getKind() == Base::StrTable; }
+  Kind getKind() const override { return StrTable; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == StrTable;
+  }
 
 private:
   const bool Dynamic;
@@ -527,27 +531,26 @@ private:
   std::vector<StringRef> Strings;
 };
 
-template <class ELFT>
-class HashTableSection final : public OutputSectionBase<ELFT> {
+template <class ELFT> class HashTableSection final : public OutputSectionBase {
   typedef typename ELFT::Word Elf_Word;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   HashTableSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  typename Base::Kind getKind() const override { return Base::HashTable; }
-  static bool classof(const Base *B) { return B->getKind() == Base::HashTable; }
+  Kind getKind() const override { return HashTable; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == HashTable;
+  }
 };
 
 // Outputs GNU Hash section. For detailed explanation see:
 // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
 template <class ELFT>
-class GnuHashTableSection final : public OutputSectionBase<ELFT> {
+class GnuHashTableSection final : public OutputSectionBase {
   typedef typename ELFT::Off Elf_Off;
   typedef typename ELFT::Word Elf_Word;
   typedef typename ELFT::uint uintX_t;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   GnuHashTableSection();
@@ -557,9 +560,9 @@ public:
   // Adds symbols to the hash table.
   // Sorts the input to satisfy GNU hash section requirements.
   void addSymbols(std::vector<SymbolTableEntry> &Symbols);
-  typename Base::Kind getKind() const override { return Base::GnuHashTable; }
-  static bool classof(const Base *B) {
-    return B->getKind() == Base::GnuHashTable;
+  Kind getKind() const override { return GnuHashTable; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == GnuHashTable;
   }
 
 private:
@@ -583,9 +586,7 @@ private:
   unsigned Shift2;
 };
 
-template <class ELFT>
-class DynamicSection final : public OutputSectionBase<ELFT> {
-  typedef OutputSectionBase<ELFT> Base;
+template <class ELFT> class DynamicSection final : public OutputSectionBase {
   typedef typename ELFT::Dyn Elf_Dyn;
   typedef typename ELFT::Rel Elf_Rel;
   typedef typename ELFT::Rela Elf_Rela;
@@ -600,12 +601,12 @@ class DynamicSection final : public Outp
   struct Entry {
     int32_t Tag;
     union {
-      OutputSectionBase<ELFT> *OutSec;
+      OutputSectionBase *OutSec;
       uint64_t Val;
       const SymbolBody *Sym;
     };
     enum KindT { SecAddr, SecSize, SymAddr, PlainInt } Kind;
-    Entry(int32_t Tag, OutputSectionBase<ELFT> *OutSec, KindT Kind = SecAddr)
+    Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
         : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
     Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
     Entry(int32_t Tag, const SymbolBody *Sym)
@@ -621,8 +622,10 @@ public:
   DynamicSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  typename Base::Kind getKind() const override { return Base::Dynamic; }
-  static bool classof(const Base *B) { return B->getKind() == Base::Dynamic; }
+  Kind getKind() const override { return Dynamic; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == Dynamic;
+  }
 
 private:
   void addEntries();
@@ -638,19 +641,17 @@ private:
 // Detailed info about internals can be found in Ian Lance Taylor's blog:
 // http://www.airs.com/blog/archives/460 (".eh_frame")
 // http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
-template <class ELFT>
-class EhFrameHeader final : public OutputSectionBase<ELFT> {
+template <class ELFT> class EhFrameHeader final : public OutputSectionBase {
   typedef typename ELFT::uint uintX_t;
-  typedef OutputSectionBase<ELFT> Base;
 
 public:
   EhFrameHeader();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addFde(uint32_t Pc, uint32_t FdeVA);
-  typename Base::Kind getKind() const override { return Base::EHFrameHdr; }
-  static bool classof(const Base *B) {
-    return B->getKind() == Base::EHFrameHdr;
+  Kind getKind() const override { return EHFrameHdr; }
+  static bool classof(const OutputSectionBase *B) {
+    return B->getKind() == EHFrameHdr;
   }
 
 private:
@@ -680,7 +681,7 @@ template <class ELFT> struct Out {
   static HashTableSection<ELFT> *HashTab;
   static OutputSection<ELFT> *Bss;
   static OutputSection<ELFT> *MipsRldMap;
-  static OutputSectionBase<ELFT> *Opd;
+  static OutputSectionBase *Opd;
   static uint8_t *OpdBuf;
   static PltSection<ELFT> *Plt;
   static RelocationSection<ELFT> *RelaDyn;
@@ -694,12 +695,12 @@ template <class ELFT> struct Out {
   static VersionTableSection<ELFT> *VerSym;
   static VersionNeedSection<ELFT> *VerNeed;
   static Elf_Phdr *TlsPhdr;
-  static OutputSectionBase<ELFT> *DebugInfo;
-  static OutputSectionBase<ELFT> *ElfHeader;
-  static OutputSectionBase<ELFT> *ProgramHeaders;
-  static OutputSectionBase<ELFT> *PreinitArray;
-  static OutputSectionBase<ELFT> *InitArray;
-  static OutputSectionBase<ELFT> *FiniArray;
+  static OutputSectionBase *DebugInfo;
+  static OutputSectionBase *ElfHeader;
+  static OutputSectionBase *ProgramHeaders;
+  static OutputSectionBase *PreinitArray;
+  static OutputSectionBase *InitArray;
+  static OutputSectionBase *FiniArray;
 };
 
 template <bool Is64Bits> struct SectionKey {
@@ -720,13 +721,13 @@ template <class ELFT> class OutputSectio
   typedef typename elf::SectionKey<ELFT::Is64Bits> Key;
 
 public:
-  std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C,
-                                                    StringRef OutsecName);
-  std::pair<OutputSectionBase<ELFT> *, bool>
+  std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C,
+                                              StringRef OutsecName);
+  std::pair<OutputSectionBase *, bool>
   create(const SectionKey<ELFT::Is64Bits> &Key, InputSectionBase<ELFT> *C);
 
 private:
-  llvm::SmallDenseMap<Key, OutputSectionBase<ELFT> *> Map;
+  llvm::SmallDenseMap<Key, OutputSectionBase *> Map;
 };
 
 template <class ELFT> uint64_t getHeaderSize() {
@@ -746,7 +747,7 @@ template <class ELFT> GotSection<ELFT> *
 template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab;
 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::Opd;
+template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
 template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
 template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
 template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
@@ -760,12 +761,12 @@ template <class ELFT> VersionDefinitionS
 template <class ELFT> VersionTableSection<ELFT> *Out<ELFT>::VerSym;
 template <class ELFT> VersionNeedSection<ELFT> *Out<ELFT>::VerNeed;
 template <class ELFT> typename ELFT::Phdr *Out<ELFT>::TlsPhdr;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::DebugInfo;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ElfHeader;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ProgramHeaders;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::PreinitArray;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::InitArray;
-template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::FiniArray;
+template <class ELFT> OutputSectionBase *Out<ELFT>::DebugInfo;
+template <class ELFT> OutputSectionBase *Out<ELFT>::ElfHeader;
+template <class ELFT> OutputSectionBase *Out<ELFT>::ProgramHeaders;
+template <class ELFT> OutputSectionBase *Out<ELFT>::PreinitArray;
+template <class ELFT> OutputSectionBase *Out<ELFT>::InitArray;
+template <class ELFT> OutputSectionBase *Out<ELFT>::FiniArray;
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Nov  9 17:23:45 2016
@@ -429,8 +429,7 @@ Symbol *SymbolTable<ELFT>::addRegular(St
 }
 
 template <typename ELFT>
-Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
-                                        OutputSectionBase<ELFT> *Section,
+Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N, OutputSectionBase *Section,
                                         uintX_t Value, uint8_t StOther) {
   Symbol *S;
   bool WasInserted;

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Nov  9 17:23:45 2016
@@ -19,7 +19,7 @@
 namespace lld {
 namespace elf {
 class Lazy;
-template <class ELFT> class OutputSectionBase;
+class OutputSectionBase;
 struct Symbol;
 
 typedef llvm::CachedHashStringRef SymName;
@@ -67,8 +67,8 @@ public:
   Symbol *addRegular(StringRef Name, uint8_t StOther,
                      InputSectionBase<ELFT> *Section, uint8_t Binding,
                      uint8_t Type, uintX_t Value);
-  Symbol *addSynthetic(StringRef N, OutputSectionBase<ELFT> *Section,
-                       uintX_t Value, uint8_t StOther);
+  Symbol *addSynthetic(StringRef N, OutputSectionBase *Section, uintX_t Value,
+                       uint8_t StOther);
   void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
                  const typename ELFT::Verdef *Verdef);
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed Nov  9 17:23:45 2016
@@ -33,7 +33,7 @@ static typename ELFT::uint getSymVA(cons
   switch (Body.kind()) {
   case SymbolBody::DefinedSyntheticKind: {
     auto &D = cast<DefinedSynthetic<ELFT>>(Body);
-    const OutputSectionBase<ELFT> *Sec = D.Section;
+    const OutputSectionBase *Sec = D.Section;
     if (!Sec)
       return D.Value;
     if (D.Value == DefinedSynthetic<ELFT>::SectionEnd)
@@ -216,7 +216,7 @@ Undefined::Undefined(uint32_t NameOffset
 
 template <typename ELFT>
 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
-                                         OutputSectionBase<ELFT> *Section)
+                                         OutputSectionBase *Section)
     : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */),
       Value(Value), Section(Section) {}
 

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed Nov  9 17:23:45 2016
@@ -31,7 +31,7 @@ class LazyObjectFile;
 class SymbolBody;
 template <class ELFT> class ObjectFile;
 template <class ELFT> class OutputSection;
-template <class ELFT> class OutputSectionBase;
+class OutputSectionBase;
 template <class ELFT> class SharedFile;
 
 struct Symbol;
@@ -249,8 +249,7 @@ InputSectionBase<ELFT> *DefinedRegular<E
 template <class ELFT> class DefinedSynthetic : public Defined {
 public:
   typedef typename ELFT::uint uintX_t;
-  DefinedSynthetic(StringRef N, uintX_t Value,
-                   OutputSectionBase<ELFT> *Section);
+  DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase *Section);
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == SymbolBody::DefinedSyntheticKind;
@@ -261,7 +260,7 @@ public:
   static const uintX_t SectionEnd = uintX_t(-1);
 
   uintX_t Value;
-  const OutputSectionBase<ELFT> *Section;
+  const OutputSectionBase *Section;
 };
 
 class Undefined : public SymbolBody {

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Nov  9 17:23:45 2016
@@ -77,13 +77,13 @@ private:
 
   std::unique_ptr<FileOutputBuffer> Buffer;
 
-  std::vector<OutputSectionBase<ELFT> *> OutputSections;
+  std::vector<OutputSectionBase *> OutputSections;
   OutputSectionFactory<ELFT> Factory;
 
   void addRelIpltSymbols();
   void addStartEndSymbols();
-  void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
-  OutputSectionBase<ELFT> *findSection(StringRef Name);
+  void addStartStopSymbols(OutputSectionBase *Sec);
+  OutputSectionBase *findSection(StringRef Name);
 
   std::vector<Phdr> Phdrs;
 
@@ -221,9 +221,9 @@ template <class ELFT> void Writer<ELFT>:
   Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
   Out<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
 
-  Out<ELFT>::ElfHeader = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
+  Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC);
   Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr);
-  Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
+  Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC);
   Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
 
   if (needsInterpSection<ELFT>()) {
@@ -411,11 +411,10 @@ static int getPPC64SectionRank(StringRef
       .Default(1);
 }
 
-template <class ELFT>
-bool elf::isRelroSection(const OutputSectionBase<ELFT> *Sec) {
+template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
   if (!Config->ZRelro)
     return false;
-  typename ELFT::uint Flags = Sec->Flags;
+  uint64_t Flags = Sec->Flags;
   if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
     return false;
   if (Flags & SHF_TLS)
@@ -434,8 +433,8 @@ bool elf::isRelroSection(const OutputSec
 }
 
 template <class ELFT>
-static bool compareSectionsNonScript(const OutputSectionBase<ELFT> *A,
-                                     const OutputSectionBase<ELFT> *B) {
+static bool compareSectionsNonScript(const OutputSectionBase *A,
+                                     const OutputSectionBase *B) {
   // Put .interp first because some loaders want to see that section
   // on the first page of the executable file when loaded into memory.
   bool AIsInterp = A->getName() == ".interp";
@@ -496,8 +495,8 @@ static bool compareSectionsNonScript(con
     return BIsNoBits;
 
   // We place RelRo section before plain r/w ones.
-  bool AIsRelRo = isRelroSection(A);
-  bool BIsRelRo = isRelroSection(B);
+  bool AIsRelRo = isRelroSection<ELFT>(A);
+  bool BIsRelRo = isRelroSection<ELFT>(B);
   if (AIsRelRo != BIsRelRo)
     return AIsRelRo;
 
@@ -512,8 +511,8 @@ static bool compareSectionsNonScript(con
 
 // Output section ordering is determined by this function.
 template <class ELFT>
-static bool compareSections(const OutputSectionBase<ELFT> *A,
-                            const OutputSectionBase<ELFT> *B) {
+static bool compareSections(const OutputSectionBase *A,
+                            const OutputSectionBase *B) {
   // For now, put sections mentioned in a linker script first.
   int AIndex = Script<ELFT>::X->getSectionIndex(A->getName());
   int BIndex = Script<ELFT>::X->getSectionIndex(B->getName());
@@ -525,7 +524,7 @@ static bool compareSections(const Output
   if (AInScript)
     return AIndex < BIndex;
 
-  return compareSectionsNonScript(A, B);
+  return compareSectionsNonScript<ELFT>(A, B);
 }
 
 // Program header entry
@@ -535,7 +534,7 @@ PhdrEntry<ELFT>::PhdrEntry(unsigned Type
   H.p_flags = Flags;
 }
 
-template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase<ELFT> *Sec) {
+template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase *Sec) {
   Last = Sec;
   if (!First)
     First = Sec;
@@ -545,9 +544,9 @@ template <class ELFT> void PhdrEntry<ELF
 }
 
 template <class ELFT>
-static Symbol *
-addOptionalSynthetic(StringRef Name, OutputSectionBase<ELFT> *Sec,
-                     typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) {
+static Symbol *addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
+                                    typename ELFT::uint Val,
+                                    uint8_t StOther = STV_HIDDEN) {
   SymbolBody *S = Symtab<ELFT>::X->find(Name);
   if (!S)
     return nullptr;
@@ -566,11 +565,11 @@ template <class ELFT> void Writer<ELFT>:
   if (Out<ELFT>::DynSymTab || !Out<ELFT>::RelaPlt)
     return;
   StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
-  addOptionalSynthetic(S, Out<ELFT>::RelaPlt, 0);
+  addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt, 0);
 
   S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
-  addOptionalSynthetic(S, Out<ELFT>::RelaPlt,
-                       DefinedSynthetic<ELFT>::SectionEnd);
+  addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt,
+                             DefinedSynthetic<ELFT>::SectionEnd);
 }
 
 // The linker is expected to define some symbols depending on
@@ -587,7 +586,7 @@ template <class ELFT> void Writer<ELFT>:
     // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
     // start of function and 'gp' pointer into GOT.
     Symbol *Sym =
-        addOptionalSynthetic("_gp_disp", Out<ELFT>::Got, MipsGPOffset);
+        addOptionalSynthetic<ELFT>("_gp_disp", Out<ELFT>::Got, MipsGPOffset);
     if (Sym)
       ElfSym<ELFT>::MipsGpDisp = Sym->body();
 
@@ -595,7 +594,7 @@ template <class ELFT> void Writer<ELFT>:
     // pointer. This symbol is used in the code generated by .cpload pseudo-op
     // in case of using -mno-shared option.
     // https://sourceware.org/ml/binutils/2004-12/msg00094.html
-    addOptionalSynthetic("__gnu_local_gp", Out<ELFT>::Got, MipsGPOffset);
+    addOptionalSynthetic<ELFT>("__gnu_local_gp", Out<ELFT>::Got, MipsGPOffset);
   }
 
   // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
@@ -649,13 +648,13 @@ template <class ELFT> void Writer<ELFT>:
 
 // Sort input sections by section name suffixes for
 // __attribute__((init_priority(N))).
-template <class ELFT> static void sortInitFini(OutputSectionBase<ELFT> *S) {
+template <class ELFT> static void sortInitFini(OutputSectionBase *S) {
   if (S)
     reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini();
 }
 
 // Sort input sections by the special rule for .ctors and .dtors.
-template <class ELFT> static void sortCtorsDtors(OutputSectionBase<ELFT> *S) {
+template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) {
   if (S)
     reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
 }
@@ -691,7 +690,7 @@ void Writer<ELFT>::addInputSec(InputSect
     reportDiscarded(IS);
     return;
   }
-  OutputSectionBase<ELFT> *Sec;
+  OutputSectionBase *Sec;
   bool IsNew;
   StringRef OutsecName = getOutputSectionName(IS->Name);
   std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
@@ -704,18 +703,18 @@ template <class ELFT> void Writer<ELFT>:
   for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections)
     addInputSec(IS);
 
-  sortInitFini(findSection(".init_array"));
-  sortInitFini(findSection(".fini_array"));
-  sortCtorsDtors(findSection(".ctors"));
-  sortCtorsDtors(findSection(".dtors"));
+  sortInitFini<ELFT>(findSection(".init_array"));
+  sortInitFini<ELFT>(findSection(".fini_array"));
+  sortCtorsDtors<ELFT>(findSection(".ctors"));
+  sortCtorsDtors<ELFT>(findSection(".dtors"));
 
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+  for (OutputSectionBase *Sec : OutputSections)
     Sec->assignOffsets();
 }
 
 template <class ELFT>
-static bool canSharePtLoad(const OutputSectionBase<ELFT> &S1,
-                           const OutputSectionBase<ELFT> &S2) {
+static bool canSharePtLoad(const OutputSectionBase &S1,
+                           const OutputSectionBase &S2) {
   if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC))
     return false;
 
@@ -767,15 +766,14 @@ template <class ELFT> void Writer<ELFT>:
   auto I = OutputSections.begin();
   auto E = OutputSections.end();
   auto NonScriptI =
-      std::find_if(OutputSections.begin(), E, [](OutputSectionBase<ELFT> *S) {
+      std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) {
         return Script<ELFT>::X->getSectionIndex(S->getName()) == INT_MAX;
       });
   while (NonScriptI != E) {
-    auto BestPos =
-        std::max_element(I, NonScriptI, [&](OutputSectionBase<ELFT> *&A,
-                                            OutputSectionBase<ELFT> *&B) {
-          bool ACanSharePtLoad = canSharePtLoad(**NonScriptI, *A);
-          bool BCanSharePtLoad = canSharePtLoad(**NonScriptI, *B);
+    auto BestPos = std::max_element(
+        I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) {
+          bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *A);
+          bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *B);
           if (ACanSharePtLoad != BCanSharePtLoad)
             return BCanSharePtLoad;
 
@@ -812,7 +810,7 @@ template <class ELFT> void Writer<ELFT>:
   // addresses of each section by section name. Add such symbols.
   if (!Config->Relocatable) {
     addStartEndSymbols();
-    for (OutputSectionBase<ELFT> *Sec : OutputSections)
+    for (OutputSectionBase *Sec : OutputSections)
       addStartStopSymbols(Sec);
   }
 
@@ -865,7 +863,7 @@ template <class ELFT> void Writer<ELFT>:
   sortSections();
 
   unsigned I = 1;
-  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+  for (OutputSectionBase *Sec : OutputSections) {
     Sec->SectionIndex = I++;
     Sec->ShName = Out<ELFT>::ShStrTab->addString(Sec->getName());
   }
@@ -878,7 +876,7 @@ template <class ELFT> void Writer<ELFT>:
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
   // of finalizing other sections.
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+  for (OutputSectionBase *Sec : OutputSections)
     if (Sec != Out<ELFT>::Dynamic)
       Sec->finalize();
 
@@ -887,7 +885,7 @@ template <class ELFT> void Writer<ELFT>:
 
   // Now that all output offsets are fixed. Finalize mergeable sections
   // to fix their maps from input offsets to output offsets.
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+  for (OutputSectionBase *Sec : OutputSections)
     Sec->finalizePieces();
 }
 
@@ -907,7 +905,7 @@ template <class ELFT> bool Writer<ELFT>:
 
 // This function add Out<ELFT>::* sections to OutputSections.
 template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
-  auto Add = [&](OutputSectionBase<ELFT> *OS) {
+  auto Add = [&](OutputSectionBase *OS) {
     if (OS)
       OutputSections.push_back(OS);
   };
@@ -958,11 +956,11 @@ template <class ELFT> void Writer<ELFT>:
 // The linker is expected to define SECNAME_start and SECNAME_end
 // symbols for a few sections. This function defines them.
 template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
-  auto Define = [&](StringRef Start, StringRef End,
-                    OutputSectionBase<ELFT> *OS) {
+  auto Define = [&](StringRef Start, StringRef End, OutputSectionBase *OS) {
     // These symbols resolve to the image base if the section does not exist.
-    addOptionalSynthetic(Start, OS, 0);
-    addOptionalSynthetic(End, OS, OS ? DefinedSynthetic<ELFT>::SectionEnd : 0);
+    addOptionalSynthetic<ELFT>(Start, OS, 0);
+    addOptionalSynthetic<ELFT>(End, OS,
+                               OS ? DefinedSynthetic<ELFT>::SectionEnd : 0);
   };
 
   Define("__preinit_array_start", "__preinit_array_end",
@@ -970,7 +968,7 @@ template <class ELFT> void Writer<ELFT>:
   Define("__init_array_start", "__init_array_end", Out<ELFT>::InitArray);
   Define("__fini_array_start", "__fini_array_end", Out<ELFT>::FiniArray);
 
-  if (OutputSectionBase<ELFT> *Sec = findSection(".ARM.exidx"))
+  if (OutputSectionBase *Sec = findSection(".ARM.exidx"))
     Define("__exidx_start", "__exidx_end", Sec);
 }
 
@@ -980,24 +978,24 @@ template <class ELFT> void Writer<ELFT>:
 // respectively. This is not requested by the ELF standard, but GNU ld and
 // gold provide the feature, and used by many programs.
 template <class ELFT>
-void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
+void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) {
   StringRef S = Sec->getName();
   if (!isValidCIdentifier(S))
     return;
-  addOptionalSynthetic(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
-  addOptionalSynthetic(Saver.save("__stop_" + S), Sec,
-                       DefinedSynthetic<ELFT>::SectionEnd, STV_DEFAULT);
+  addOptionalSynthetic<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
+  addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec,
+                             DefinedSynthetic<ELFT>::SectionEnd, STV_DEFAULT);
 }
 
 template <class ELFT>
-OutputSectionBase<ELFT> *Writer<ELFT>::findSection(StringRef Name) {
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) {
+  for (OutputSectionBase *Sec : OutputSections)
     if (Sec->getName() == Name)
       return Sec;
   return nullptr;
 }
 
-template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
+template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) {
   if (!(Sec->Flags & SHF_ALLOC))
     return false;
 
@@ -1034,7 +1032,7 @@ template <class ELFT> std::vector<PhdrEn
   Hdr.add(Out<ELFT>::ProgramHeaders);
 
   // PT_INTERP must be the second entry if exists.
-  if (OutputSectionBase<ELFT> *Sec = findSection(".interp")) {
+  if (OutputSectionBase *Sec = findSection(".interp")) {
     Phdr &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags());
     Hdr.add(Sec);
   }
@@ -1051,7 +1049,7 @@ template <class ELFT> std::vector<PhdrEn
   Phdr RelRo(PT_GNU_RELRO, PF_R);
   Phdr Note(PT_NOTE, PF_R);
   Phdr ARMExidx(PT_ARM_EXIDX, PF_R);
-  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+  for (OutputSectionBase *Sec : OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
 
@@ -1061,7 +1059,7 @@ template <class ELFT> std::vector<PhdrEn
     if (Sec->Flags & SHF_TLS)
       TlsHdr.add(Sec);
 
-    if (!needsPtLoad(Sec))
+    if (!needsPtLoad<ELFT>(Sec))
       continue;
 
     // Segments are contiguous memory regions that has the same attributes
@@ -1077,7 +1075,7 @@ template <class ELFT> std::vector<PhdrEn
 
     Load->add(Sec);
 
-    if (isRelroSection(Sec))
+    if (isRelroSection<ELFT>(Sec))
       RelRo.add(Sec);
     if (Sec->Type == SHT_NOTE)
       Note.add(Sec);
@@ -1109,7 +1107,7 @@ template <class ELFT> std::vector<PhdrEn
   // PT_OPENBSD_RANDOMIZE specifies the location and size of a part of the
   // memory image of the program that must be filled with random data before any
   // code in the object is executed.
-  if (OutputSectionBase<ELFT> *Sec = findSection(".openbsd.randomdata")) {
+  if (OutputSectionBase *Sec = findSection(".openbsd.randomdata")) {
     Phdr &Hdr = *AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags());
     Hdr.add(Sec);
   }
@@ -1154,8 +1152,8 @@ template <class ELFT> void Writer<ELFT>:
     auto I = std::find(OutputSections.begin(), End, P.Last);
     if (I == End || (I + 1) == End)
       continue;
-    OutputSectionBase<ELFT> *Sec = *(I + 1);
-    if (needsPtLoad(Sec))
+    OutputSectionBase *Sec = *(I + 1);
+    if (needsPtLoad<ELFT>(Sec))
       Sec->PageAlign = true;
   }
 }
@@ -1175,7 +1173,7 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT> void Writer<ELFT>::assignAddresses() {
   uintX_t VA = Config->ImageBase + getHeaderSize<ELFT>();
   uintX_t ThreadBssOffset = 0;
-  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+  for (OutputSectionBase *Sec : OutputSections) {
     uintX_t Alignment = Sec->Addralign;
     if (Sec->PageAlign)
       Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
@@ -1185,7 +1183,7 @@ template <class ELFT> void Writer<ELFT>:
       VA = I->second;
 
     // We only assign VAs to allocated sections.
-    if (needsPtLoad(Sec)) {
+    if (needsPtLoad<ELFT>(Sec)) {
       VA = alignTo(VA, Alignment);
       Sec->Addr = VA;
       VA += Sec->Size;
@@ -1203,13 +1201,13 @@ template <class ELFT> void Writer<ELFT>:
 // virtual address (modulo the page size) so that the loader can load
 // executables without any address adjustment.
 template <class ELFT, class uintX_t>
-static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase<ELFT> *Sec) {
+static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) {
   uintX_t Alignment = Sec->Addralign;
   if (Sec->PageAlign)
     Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
   Off = alignTo(Off, Alignment);
 
-  OutputSectionBase<ELFT> *First = Sec->FirstInPtLoad;
+  OutputSectionBase *First = Sec->FirstInPtLoad;
   // If the section is not in a PT_LOAD, we have no other constraint.
   if (!First)
     return Off;
@@ -1222,7 +1220,7 @@ static uintX_t getFileAlignment(uintX_t
 }
 
 template <class ELFT, class uintX_t>
-void setOffset(OutputSectionBase<ELFT> *Sec, uintX_t &Off) {
+void setOffset(OutputSectionBase *Sec, uintX_t &Off) {
   if (Sec->Type == SHT_NOBITS) {
     Sec->Offset = Off;
     return;
@@ -1235,20 +1233,20 @@ void setOffset(OutputSectionBase<ELFT> *
 
 template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
   uintX_t Off = 0;
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+  for (OutputSectionBase *Sec : OutputSections)
     if (Sec->Flags & SHF_ALLOC)
-      setOffset(Sec, Off);
+      setOffset<ELFT>(Sec, Off);
   FileSize = alignTo(Off, sizeof(uintX_t));
 }
 
 // Assign file offsets to output sections.
 template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
   uintX_t Off = 0;
-  setOffset(Out<ELFT>::ElfHeader, Off);
-  setOffset(Out<ELFT>::ProgramHeaders, Off);
+  setOffset<ELFT>(Out<ELFT>::ElfHeader, Off);
+  setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off);
 
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
-    setOffset(Sec, Off);
+  for (OutputSectionBase *Sec : OutputSections)
+    setOffset<ELFT>(Sec, Off);
 
   SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
   FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
@@ -1259,8 +1257,8 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT> void Writer<ELFT>::setPhdrs() {
   for (Phdr &P : Phdrs) {
     Elf_Phdr &H = P.H;
-    OutputSectionBase<ELFT> *First = P.First;
-    OutputSectionBase<ELFT> *Last = P.Last;
+    OutputSectionBase *First = P.First;
+    OutputSectionBase *Last = P.Last;
     if (First) {
       H.p_filesz = Last->Offset - First->Offset;
       if (Last->Type != SHT_NOBITS)
@@ -1382,8 +1380,8 @@ template <class ELFT> void Writer<ELFT>:
 
   // Write the section header table. Note that the first table entry is null.
   auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
-    Sec->writeHeaderTo(++SHdrs);
+  for (OutputSectionBase *Sec : OutputSections)
+    Sec->writeHeaderTo<ELFT>(++SHdrs);
 }
 
 template <class ELFT> void Writer<ELFT>::openFile() {
@@ -1398,7 +1396,7 @@ template <class ELFT> void Writer<ELFT>:
 
 template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
   uint8_t *Buf = Buffer->getBufferStart();
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+  for (OutputSectionBase *Sec : OutputSections)
     if (Sec->Flags & SHF_ALLOC)
       Sec->writeTo(Buf + Sec->Offset);
 }
@@ -1477,11 +1475,11 @@ template <class ELFT> void Writer<ELFT>:
     Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset);
   }
 
-  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+  for (OutputSectionBase *Sec : OutputSections)
     if (Sec != Out<ELFT>::Opd && Sec != Out<ELFT>::EhFrameHdr)
       Sec->writeTo(Buf + Sec->Offset);
 
-  OutputSectionBase<ELFT> *ARMExidx = findSection(".ARM.exidx");
+  OutputSectionBase *ARMExidx = findSection(".ARM.exidx");
   if (!Config->Relocatable)
     if (auto *OS = dyn_cast_or_null<OutputSection<ELFT>>(ARMExidx))
       sortARMExidx(Buf + OS->Offset, OS->Addr, OS->Size);
@@ -1512,10 +1510,10 @@ template struct elf::PhdrEntry<ELF32BE>;
 template struct elf::PhdrEntry<ELF64LE>;
 template struct elf::PhdrEntry<ELF64BE>;
 
-template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase<ELF32LE> *);
-template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase<ELF32BE> *);
-template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase<ELF64LE> *);
-template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase<ELF64BE> *);
+template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *);
+template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *);
+template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase *);
+template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase *);
 
 template void elf::reportDiscarded<ELF32LE>(InputSectionBase<ELF32LE> *);
 template void elf::reportDiscarded<ELF32BE>(InputSectionBase<ELF32BE> *);

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=286414&r1=286413&r2=286414&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Wed Nov  9 17:23:45 2016
@@ -17,24 +17,24 @@
 namespace lld {
 namespace elf {
 class InputFile;
-template <class ELFT> class OutputSectionBase;
+class OutputSectionBase;
 template <class ELFT> class InputSectionBase;
 template <class ELFT> class ObjectFile;
 template <class ELFT> class SymbolTable;
 template <class ELFT> void writeResult();
 template <class ELFT> void markLive();
-template <class ELFT> bool isRelroSection(const OutputSectionBase<ELFT> *Sec);
+template <class ELFT> bool isRelroSection(const OutputSectionBase *Sec);
 
 // This describes a program header entry.
 // Each contains type, access flags and range of output sections that will be
 // placed in it.
 template <class ELFT> struct PhdrEntry {
   PhdrEntry(unsigned Type, unsigned Flags);
-  void add(OutputSectionBase<ELFT> *Sec);
+  void add(OutputSectionBase *Sec);
 
   typename ELFT::Phdr H = {};
-  OutputSectionBase<ELFT> *First = nullptr;
-  OutputSectionBase<ELFT> *Last = nullptr;
+  OutputSectionBase *First = nullptr;
+  OutputSectionBase *Last = nullptr;
   bool HasLMA = false;
 };
 




More information about the llvm-commits mailing list