[lld] r296127 - Merge OutputSectionBase and OutputSection. NFC.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 24 07:07:30 PST 2017


Author: rafael
Date: Fri Feb 24 09:07:30 2017
New Revision: 296127

URL: http://llvm.org/viewvc/llvm-project?rev=296127&view=rev
Log:
Merge OutputSectionBase and OutputSection. NFC.

Now that all special sections are SyntheticSections, we only need one
OutputSection class.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/MapFile.cpp
    lld/trunk/ELF/MapFile.h
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Relocations.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Thunks.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/ELF/Writer.h

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Feb 24 09:07:30 2017
@@ -118,7 +118,7 @@ uint64_t InputSectionBase::getOffset(uin
 }
 
 template <class ELFT>
-OutputSectionBase *InputSectionBase::getOutputSection() const {
+OutputSection *InputSectionBase::getOutputSection() const {
   if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(this))
     return MS->MergeSec ? MS->MergeSec->OutSec : nullptr;
   if (auto *EH = dyn_cast<EhInputSection<ELFT>>(this))
@@ -827,10 +827,10 @@ template InputSectionBase *InputSectionB
 template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64LE>() const;
 template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64BE>() const;
 
-template OutputSectionBase *InputSectionBase::getOutputSection<ELF32LE>() const;
-template OutputSectionBase *InputSectionBase::getOutputSection<ELF32BE>() const;
-template OutputSectionBase *InputSectionBase::getOutputSection<ELF64LE>() const;
-template OutputSectionBase *InputSectionBase::getOutputSection<ELF64BE>() const;
+template OutputSection *InputSectionBase::getOutputSection<ELF32LE>() const;
+template OutputSection *InputSectionBase::getOutputSection<ELF32BE>() const;
+template OutputSection *InputSectionBase::getOutputSection<ELF64LE>() const;
+template OutputSection *InputSectionBase::getOutputSection<ELF64BE>() const;
 
 template InputSectionBase *InputSection::getRelocatedSection<ELF32LE>();
 template InputSectionBase *InputSection::getRelocatedSection<ELF32BE>();

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Fri Feb 24 09:07:30 2017
@@ -31,8 +31,7 @@ template <class ELFT> class DefinedRegul
 template <class ELFT> class EhFrameSection;
 template <class ELFT> class MergeSyntheticSection;
 template <class ELFT> class ObjectFile;
-template <class ELFT> class OutputSection;
-class OutputSectionBase;
+class OutputSection;
 
 // This corresponds to a section of an input file.
 class InputSectionBase {
@@ -78,7 +77,7 @@ public:
                    uint64_t Entsize, uint32_t Link, uint32_t Info,
                    uint64_t Addralign, ArrayRef<uint8_t> Data, StringRef Name,
                    Kind SectionKind);
-  OutputSectionBase *OutSec = nullptr;
+  OutputSection *OutSec = nullptr;
 
   // Relocations that refer to this section.
   const void *FirstRelocation = nullptr;
@@ -110,7 +109,7 @@ public:
   // Returns the size of this section (even if this is a common or BSS.)
   template <class ELFT> size_t getSize() const;
 
-  template <class ELFT> OutputSectionBase *getOutputSection() const;
+  template <class ELFT> OutputSection *getOutputSection() const;
 
   template <class ELFT> ObjectFile<ELFT> *getFile() const;
 

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Feb 24 09:07:30 2017
@@ -72,7 +72,7 @@ template <class ELFT> static SymbolBody
 template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
   Symbol *Sym;
   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  const OutputSectionBase *Sec =
+  const OutputSection *Sec =
       ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
   std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
@@ -397,7 +397,7 @@ void LinkerScript<ELFT>::addOrphanSectio
       Factory.addInputSec(S, getOutputSectionName(S->Name));
 }
 
-template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
+template <class ELFT> static bool isTbss(OutputSection *Sec) {
   return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
 }
 
@@ -438,16 +438,11 @@ template <class ELFT> void LinkerScript<
 template <class ELFT> void LinkerScript<ELFT>::flush() {
   if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second)
     return;
-  if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) {
-    for (InputSection *I : OutSec->Sections)
-      output(I);
-  } else {
-    Dot += CurOutSec->Size;
-  }
+  for (InputSection *I : CurOutSec->Sections)
+    output(I);
 }
 
-template <class ELFT>
-void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) {
+template <class ELFT> void LinkerScript<ELFT>::switchTo(OutputSection *Sec) {
   if (CurOutSec == Sec)
     return;
   if (AlreadyOutputOS.count(Sec))
@@ -512,12 +507,12 @@ template <class ELFT> void LinkerScript<
 }
 
 template <class ELFT>
-static OutputSectionBase *
-findSection(StringRef Name, const std::vector<OutputSectionBase *> &Sections) {
+static OutputSection *
+findSection(StringRef Name, const std::vector<OutputSection *> &Sections) {
   auto End = Sections.end();
-  auto HasName = [=](OutputSectionBase *Sec) { return Sec->Name == Name; };
+  auto HasName = [=](OutputSection *Sec) { return Sec->Name == Name; };
   auto I = std::find_if(Sections.begin(), End, HasName);
-  std::vector<OutputSectionBase *> Ret;
+  std::vector<OutputSection *> Ret;
   if (I == End)
     return nullptr;
   assert(std::find_if(I + 1, End, HasName) == End);
@@ -529,7 +524,7 @@ findSection(StringRef Name, const std::v
 // returned. Otherwise, a nullptr is returned.
 template <class ELFT>
 MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd,
-                                                   OutputSectionBase *Sec) {
+                                                   OutputSection *Sec) {
   // If a memory region name was specified in the output section command,
   // then try to find that region first.
   if (!Cmd->MemoryRegionName.empty()) {
@@ -568,7 +563,7 @@ void LinkerScript<ELFT>::assignOffsets(O
     uintX_t D = Dot;
     LMAOffset = [=] { return Cmd->LMAExpr(D) - D; };
   }
-  OutputSectionBase *Sec = findSection<ELFT>(Cmd->Name, *OutputSections);
+  OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections);
   if (!Sec)
     return;
 
@@ -634,8 +629,7 @@ template <class ELFT> void LinkerScript<
     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
     if (!Cmd)
       continue;
-    if (OutputSectionBase *Sec =
-            findSection<ELFT>(Cmd->Name, *OutputSections)) {
+    if (OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections)) {
       Flags = Sec->Flags;
       Type = Sec->Type;
       continue;
@@ -644,7 +638,7 @@ template <class ELFT> void LinkerScript<
     if (isAllSectionDescription(*Cmd))
       continue;
 
-    auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags);
+    auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags);
     OutputSections->push_back(OutSec);
   }
 }
@@ -751,7 +745,7 @@ template <class ELFT> void LinkerScript<
       ++CmdIndex;
   }
 
-  for (OutputSectionBase *Sec : *OutputSections) {
+  for (OutputSection *Sec : *OutputSections) {
     StringRef Name = Sec->Name;
 
     // Find the last spot where we can insert a command and still get the
@@ -794,7 +788,7 @@ void LinkerScript<ELFT>::assignAddresses
   // To handle that, create a dummy aether section that fills the void before
   // the linker scripts switches to another section. It has an index of one
   // which will map to whatever the first actual section is.
-  auto *Aether = make<OutputSectionBase>("", 0, SHF_ALLOC);
+  auto *Aether = make<OutputSection>("", 0, SHF_ALLOC);
   Aether->SectionIndex = 1;
   switchTo(Aether);
 
@@ -814,7 +808,7 @@ void LinkerScript<ELFT>::assignAddresses
   }
 
   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
-  for (OutputSectionBase *Sec : *OutputSections) {
+  for (OutputSection *Sec : *OutputSections) {
     if (Sec->Flags & SHF_ALLOC)
       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
     else
@@ -846,7 +840,7 @@ template <class ELFT> std::vector<PhdrEn
   }
 
   // Add output sections to program headers.
-  for (OutputSectionBase *Sec : *OutputSections) {
+  for (OutputSection *Sec : *OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
 
@@ -936,11 +930,11 @@ template <class ELFT> bool LinkerScript<
 }
 
 template <class ELFT>
-const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
-                                                              StringRef Name) {
-  static OutputSectionBase FakeSec("", 0, 0);
+const OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
+                                                          StringRef Name) {
+  static OutputSection FakeSec("", 0, 0);
 
-  for (OutputSectionBase *Sec : *OutputSections)
+  for (OutputSection *Sec : *OutputSections)
     if (Sec->Name == Name)
       return Sec;
 
@@ -956,7 +950,7 @@ const OutputSectionBase *LinkerScript<EL
 // be empty. That is why this function is different from getOutputSection().
 template <class ELFT>
 uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
-  for (OutputSectionBase *Sec : *OutputSections)
+  for (OutputSection *Sec : *OutputSections)
     if (Sec->Name == Name)
       return Sec->Size;
   return 0;
@@ -988,7 +982,7 @@ template <class ELFT> bool LinkerScript<
 // specific section but isn't absolute at the same time, so we try
 // to find suitable section for it as well.
 template <class ELFT>
-const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
+const OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
   if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))
     return SymbolTableSection<ELFT>::getOutputSection(Sym);
   return CurOutSec;
@@ -1646,7 +1640,7 @@ Expr ScriptParser::readExpr() {
 static Expr combine(StringRef Op, Expr L, Expr R) {
   auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };
   auto GetOutSec = [=] {
-    const OutputSectionBase *S = L.Section();
+    const OutputSection *S = L.Section();
     return S ? S : R.Section();
   };
 

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Feb 24 09:07:30 2017
@@ -33,7 +33,7 @@ class ScriptParser;
 class SymbolBody;
 class InputSectionBase;
 class InputSection;
-class OutputSectionBase;
+class OutputSection;
 template <class ELFT> class OutputSectionFactory;
 class InputSectionBase;
 
@@ -47,13 +47,13 @@ struct Expr {
 
   // If expression is section-relative the function below is used
   // to get the output section pointer.
-  std::function<const OutputSectionBase *()> Section;
+  std::function<const OutputSection *()> Section;
 
   uint64_t operator()(uint64_t Dot) const { return Val(Dot); }
   operator bool() const { return (bool)Val; }
 
   Expr(std::function<uint64_t(uint64_t)> Val, std::function<bool()> IsAbsolute,
-       std::function<const OutputSectionBase *()> Section)
+       std::function<const OutputSection *()> Section)
       : Val(Val), IsAbsolute(IsAbsolute), Section(Section) {}
   template <typename T>
   Expr(T V) : Expr(V, [] { return true; }, [] { return nullptr; }) {}
@@ -213,9 +213,9 @@ public:
   virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0;
   virtual bool isDefined(StringRef S) = 0;
   virtual bool isAbsolute(StringRef S) = 0;
-  virtual const OutputSectionBase *getSymbolSection(StringRef S) = 0;
-  virtual const OutputSectionBase *getOutputSection(const Twine &Loc,
-                                                    StringRef S) = 0;
+  virtual const OutputSection *getSymbolSection(StringRef S) = 0;
+  virtual const OutputSection *getOutputSection(const Twine &Loc,
+                                                StringRef S) = 0;
   virtual uint64_t getOutputSectionSize(StringRef S) = 0;
 };
 
@@ -268,12 +268,11 @@ public:
   uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
   bool isDefined(StringRef S) override;
   bool isAbsolute(StringRef S) override;
-  const OutputSectionBase *getSymbolSection(StringRef S) override;
-  const OutputSectionBase *getOutputSection(const Twine &Loc,
-                                            StringRef S) override;
+  const OutputSection *getSymbolSection(StringRef S) override;
+  const OutputSection *getOutputSection(const Twine &Loc, StringRef S) override;
   uint64_t getOutputSectionSize(StringRef S) override;
 
-  std::vector<OutputSectionBase *> *OutputSections;
+  std::vector<OutputSection *> *OutputSections;
 
   int getSectionIndex(StringRef Name);
 
@@ -294,19 +293,18 @@ private:
   std::vector<size_t> getPhdrIndices(StringRef SectionName);
   size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName);
 
-  MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd,
-                                 OutputSectionBase *Sec);
+  MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd, OutputSection *Sec);
 
   uintX_t Dot;
   std::function<uint64_t()> LMAOffset;
-  OutputSectionBase *CurOutSec = nullptr;
+  OutputSection *CurOutSec = nullptr;
   MemoryRegion *CurMemRegion = nullptr;
   uintX_t ThreadBssOffset = 0;
-  void switchTo(OutputSectionBase *Sec);
+  void switchTo(OutputSection *Sec);
   void flush();
   void output(InputSection *Sec);
   void process(BaseCommand &Base);
-  llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS;
+  llvm::DenseSet<OutputSection *> AlreadyOutputOS;
   llvm::DenseSet<InputSectionBase *> AlreadyOutputIS;
 };
 

Modified: lld/trunk/ELF/MapFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.cpp (original)
+++ lld/trunk/ELF/MapFile.cpp Fri Feb 24 09:07:30 2017
@@ -95,26 +95,25 @@ static void writeInputSection(raw_fd_ost
 
 template <class ELFT>
 static void writeMapFile2(raw_fd_ostream &OS,
-                          ArrayRef<OutputSectionBase *> OutputSections) {
+                          ArrayRef<OutputSection *> OutputSections) {
   int Width = ELFT::Is64Bits ? 16 : 8;
 
   OS << left_justify("Address", Width) << ' ' << left_justify("Size", Width)
      << " Align Out     In      File    Symbol\n";
 
-  for (OutputSectionBase *Sec : OutputSections) {
+  for (OutputSection *Sec : OutputSections) {
     writeOutSecLine(OS, Width, Sec->Addr, Sec->Size, Sec->Addralign, Sec->Name);
     OS << '\n';
 
     StringRef PrevName = "";
-    Sec->forEachInputSection([&](InputSectionBase *S) {
-      if (const auto *IS = dyn_cast<InputSection>(S))
-        writeInputSection<ELFT>(OS, IS, PrevName);
-    });
+    for (InputSection *IS : Sec->Sections) {
+      writeInputSection<ELFT>(OS, IS, PrevName);
+    }
   }
 }
 
 template <class ELFT>
-void elf::writeMapFile(ArrayRef<OutputSectionBase *> OutputSections) {
+void elf::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
   if (Config->MapFile.empty())
     return;
 
@@ -126,7 +125,7 @@ void elf::writeMapFile(ArrayRef<OutputSe
     writeMapFile2<ELFT>(OS, OutputSections);
 }
 
-template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionBase *>);
-template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionBase *>);
-template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionBase *>);
-template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionBase *>);
+template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSection *>);
+template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSection *>);
+template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSection *>);
+template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSection *>);

Modified: lld/trunk/ELF/MapFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.h (original)
+++ lld/trunk/ELF/MapFile.h Fri Feb 24 09:07:30 2017
@@ -15,7 +15,7 @@
 namespace lld {
 namespace elf {
 template <class ELFT>
-void writeMapFile(llvm::ArrayRef<OutputSectionBase *> OutputSections);
+void writeMapFile(llvm::ArrayRef<OutputSection *> OutputSections);
 }
 }
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Feb 24 09:07:30 2017
@@ -30,15 +30,7 @@ using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf;
 
-OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type,
-                                     uint64_t Flags)
-    : Name(Name) {
-  this->Type = Type;
-  this->Flags = Flags;
-  this->Addralign = 1;
-}
-
-uint32_t OutputSectionBase::getPhdrFlags() const {
+uint32_t OutputSection::getPhdrFlags() const {
   uint32_t Ret = PF_R;
   if (Flags & SHF_WRITE)
     Ret |= PF_W;
@@ -48,7 +40,7 @@ uint32_t OutputSectionBase::getPhdrFlags
 }
 
 template <class ELFT>
-void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) {
+void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) {
   Shdr->sh_entsize = Entsize;
   Shdr->sh_addralign = Addralign;
   Shdr->sh_type = Type;
@@ -78,10 +70,24 @@ template <class ELFT> static uint64_t ge
   }
 }
 
-template <class ELFT>
-OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags)
-    : OutputSectionBase(Name, Type, Flags) {
-  this->Entsize = getEntsize<ELFT>(Type);
+OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
+    : Name(Name), Addralign(1), Flags(Flags), Type(Type) {
+  switch (Config->EKind) {
+  case ELFNoneKind:
+    llvm_unreachable("unknown kind");
+  case ELF32LEKind:
+    this->Entsize = getEntsize<ELF32LE>(Type);
+    break;
+  case ELF32BEKind:
+    this->Entsize = getEntsize<ELF32BE>(Type);
+    break;
+  case ELF64LEKind:
+    this->Entsize = getEntsize<ELF64LE>(Type);
+    break;
+  case ELF64BEKind:
+    this->Entsize = getEntsize<ELF64BE>(Type);
+    break;
+  }
 }
 
 template <typename ELFT>
@@ -92,18 +98,18 @@ static bool compareByFilePosition(InputS
     return false;
   auto *LA = cast<InputSection>(A->template getLinkOrderDep<ELFT>());
   auto *LB = cast<InputSection>(B->template getLinkOrderDep<ELFT>());
-  OutputSectionBase *AOut = LA->OutSec;
-  OutputSectionBase *BOut = LB->OutSec;
+  OutputSection *AOut = LA->OutSec;
+  OutputSection *BOut = LB->OutSec;
   if (AOut != BOut)
     return AOut->SectionIndex < BOut->SectionIndex;
   return LA->OutSecOff < LB->OutSecOff;
 }
 
-template <class ELFT> void OutputSection<ELFT>::finalize() {
+template <class ELFT> void OutputSection::finalize() {
   if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
     std::sort(Sections.begin(), Sections.end(), compareByFilePosition<ELFT>);
     Size = 0;
-    assignOffsets();
+    assignOffsets<ELFT>();
 
     // We must preserve the link order dependency of sections with the
     // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
@@ -128,8 +134,7 @@ template <class ELFT> void OutputSection
   this->Info = S->OutSec->SectionIndex;
 }
 
-template <class ELFT>
-void OutputSection<ELFT>::addSection(InputSectionBase *C) {
+void OutputSection::addSection(InputSectionBase *C) {
   assert(C->Live);
   auto *S = cast<InputSection>(C);
   Sections.push_back(S);
@@ -141,17 +146,10 @@ void OutputSection<ELFT>::addSection(Inp
     this->Entsize = S->Entsize;
 }
 
-template <class ELFT>
-void OutputSection<ELFT>::forEachInputSection(
-    std::function<void(InputSectionBase *)> F) {
-  for (InputSection *S : Sections)
-    F(S);
-}
-
 // This function is called after we sort input sections
 // and scan relocations to setup sections' offsets.
-template <class ELFT> void OutputSection<ELFT>::assignOffsets() {
-  uintX_t Off = this->Size;
+template <class ELFT> void OutputSection::assignOffsets() {
+  uint64_t Off = this->Size;
   for (InputSection *S : Sections) {
     Off = alignTo(Off, S->Alignment);
     S->OutSecOff = Off;
@@ -160,8 +158,7 @@ template <class ELFT> void OutputSection
   this->Size = Off;
 }
 
-template <class ELFT>
-void OutputSection<ELFT>::sort(std::function<int(InputSectionBase *S)> Order) {
+void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) {
   typedef std::pair<unsigned, InputSection *> Pair;
   auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
 
@@ -180,7 +177,7 @@ void OutputSection<ELFT>::sort(std::func
 // because the compiler keeps the original initialization order in a
 // translation unit and we need to respect that.
 // For more detail, read the section of the GCC's manual about init_priority.
-template <class ELFT> void OutputSection<ELFT>::sortInitFini() {
+void OutputSection::sortInitFini() {
   // Sort sections by priority.
   sort([](InputSectionBase *S) { return getPriority(S->Name); });
 }
@@ -239,7 +236,7 @@ static bool compCtors(const InputSection
 // Sorts input sections by the special rules for .ctors and .dtors.
 // Unfortunately, the rules are different from the one for .{init,fini}_array.
 // Read the comment above.
-template <class ELFT> void OutputSection<ELFT>::sortCtorsDtors() {
+void OutputSection::sortCtorsDtors() {
   std::stable_sort(Sections.begin(), Sections.end(), compCtors);
 }
 
@@ -254,7 +251,7 @@ void fill(uint8_t *Buf, size_t Size, uin
   memcpy(Buf + I, V, Size - I);
 }
 
-template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
+template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
   Loc = Buf;
   if (uint32_t Filler = Script<ELFT>::X->getFiller(this->Name))
     fill(Buf, this->Size, Filler);
@@ -331,7 +328,7 @@ static SectionKey createKey(InputSection
 
 template <class ELFT>
 OutputSectionFactory<ELFT>::OutputSectionFactory(
-    std::vector<OutputSectionBase *> &OutputSections)
+    std::vector<OutputSection *> &OutputSections)
     : OutputSections(OutputSections) {}
 
 static uint64_t getIncompatibleFlags(uint64_t Flags) {
@@ -367,7 +364,7 @@ void OutputSectionFactory<ELFT>::addInpu
 
   SectionKey Key = createKey<ELFT>(IS, OutsecName);
   uintX_t Flags = getOutFlags<ELFT>(IS);
-  OutputSectionBase *&Sec = Map[Key];
+  OutputSection *&Sec = Map[Key];
   if (Sec) {
     if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
       error("Section has flags incompatible with others with the same name " +
@@ -386,7 +383,7 @@ void OutputSectionFactory<ELFT>::addInpu
       In<ELFT>::EhFrame->addSection(IS);
       return;
     }
-    Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags);
+    Sec = make<OutputSection>(Key.Name, Type, Flags);
     OutputSections.push_back(Sec);
   }
 
@@ -416,15 +413,25 @@ bool DenseMapInfo<SectionKey>::isEqual(c
 namespace lld {
 namespace elf {
 
-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 OutputSection<ELF32LE>;
-template class OutputSection<ELF32BE>;
-template class OutputSection<ELF64LE>;
-template class OutputSection<ELF64BE>;
+template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
+template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
+template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
+template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
+
+template void OutputSection::assignOffsets<ELF32LE>();
+template void OutputSection::assignOffsets<ELF32BE>();
+template void OutputSection::assignOffsets<ELF64LE>();
+template void OutputSection::assignOffsets<ELF64BE>();
+
+template void OutputSection::finalize<ELF32LE>();
+template void OutputSection::finalize<ELF32BE>();
+template void OutputSection::finalize<ELF64LE>();
+template void OutputSection::finalize<ELF64BE>();
+
+template void OutputSection::writeTo<ELF32LE>(uint8_t *Buf);
+template void OutputSection::writeTo<ELF32BE>(uint8_t *Buf);
+template void OutputSection::writeTo<ELF64LE>(uint8_t *Buf);
+template void OutputSection::writeTo<ELF64BE>(uint8_t *Buf);
 
 template class OutputSectionFactory<ELF32LE>;
 template class OutputSectionFactory<ELF32BE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Feb 24 09:07:30 2017
@@ -27,34 +27,23 @@ template <class ELFT> class EhInputSecti
 class InputSection;
 class InputSectionBase;
 template <class ELFT> class MergeInputSection;
-template <class ELFT> class OutputSection;
+class OutputSection;
 template <class ELFT> class ObjectFile;
 template <class ELFT> class SharedFile;
 template <class ELFT> class SharedSymbol;
 template <class ELFT> class DefinedRegular;
 
 // This represents a section in an output file.
-// Different sub classes represent different types of sections. Some contain
-// input sections, others are created by the linker.
+// It is composed of multiple InputSections.
 // The writer creates multiple OutputSections and assign them unique,
 // non-overlapping file offsets and VAs.
-class OutputSectionBase {
+class OutputSection final {
 public:
-  enum Kind {
-    Base,
-    Regular,
-  };
+  OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
 
-  OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags);
   uint64_t getLMA() const { return Addr + LMAOffset; }
   template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
 
-  virtual void addSection(InputSectionBase *C) {}
-  virtual Kind getKind() const { return Base; }
-  static bool classof(const OutputSectionBase *B) {
-    return B->getKind() == Base;
-  }
-
   unsigned SectionIndex;
 
   uint32_t getPhdrFlags() const;
@@ -74,13 +63,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 *FirstInPtLoad = nullptr;
-
-  virtual void finalize() {}
-  virtual void forEachInputSection(std::function<void(InputSectionBase *)> F) {}
-  virtual void assignOffsets() {}
-  virtual void writeTo(uint8_t *Buf) {}
-  virtual ~OutputSectionBase() = default;
+  OutputSection *FirstInPtLoad = nullptr;
 
   StringRef Name;
 
@@ -96,29 +79,14 @@ public:
   uint32_t Type = 0;
   uint32_t Info = 0;
   uint32_t Link = 0;
-};
-
-template <class ELFT> class OutputSection final : public OutputSectionBase {
 
-public:
-  typedef typename ELFT::Shdr Elf_Shdr;
-  typedef typename ELFT::Sym Elf_Sym;
-  typedef typename ELFT::Rel Elf_Rel;
-  typedef typename ELFT::Rela Elf_Rela;
-  typedef typename ELFT::uint uintX_t;
-  OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
-  void addSection(InputSectionBase *C) override;
+  void addSection(InputSectionBase *C);
   void sort(std::function<int(InputSectionBase *S)> Order);
   void sortInitFini();
   void sortCtorsDtors();
-  void writeTo(uint8_t *Buf) override;
-  void finalize() override;
-  void forEachInputSection(std::function<void(InputSectionBase *)> F) override;
-  void assignOffsets() override;
-  Kind getKind() const override { return Regular; }
-  static bool classof(const OutputSectionBase *B) {
-    return B->getKind() == Regular;
-  }
+  template <class ELFT> void writeTo(uint8_t *Buf);
+  template <class ELFT> void finalize();
+  template <class ELFT> void assignOffsets();
   std::vector<InputSection *> Sections;
 
   // Location in the output buffer.
@@ -133,17 +101,17 @@ template <class ELFT> struct Out {
   typedef typename ELFT::Phdr Elf_Phdr;
 
   static uint8_t First;
-  static OutputSection<ELFT> *Bss;
-  static OutputSection<ELFT> *BssRelRo;
-  static OutputSectionBase *Opd;
+  static OutputSection *Bss;
+  static OutputSection *BssRelRo;
+  static OutputSection *Opd;
   static uint8_t *OpdBuf;
   static PhdrEntry *TlsPhdr;
-  static OutputSectionBase *DebugInfo;
-  static OutputSectionBase *ElfHeader;
-  static OutputSectionBase *ProgramHeaders;
-  static OutputSectionBase *PreinitArray;
-  static OutputSectionBase *InitArray;
-  static OutputSectionBase *FiniArray;
+  static OutputSection *DebugInfo;
+  static OutputSection *ElfHeader;
+  static OutputSection *ProgramHeaders;
+  static OutputSection *PreinitArray;
+  static OutputSection *InitArray;
+  static OutputSection *FiniArray;
 };
 
 struct SectionKey {
@@ -174,13 +142,13 @@ template <class ELFT> class OutputSectio
   typedef typename ELFT::uint uintX_t;
 
 public:
-  OutputSectionFactory(std::vector<OutputSectionBase *> &OutputSections);
+  OutputSectionFactory(std::vector<OutputSection *> &OutputSections);
   ~OutputSectionFactory();
   void addInputSec(InputSectionBase *IS, StringRef OutsecName);
 
 private:
-  llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map;
-  std::vector<OutputSectionBase *> &OutputSections;
+  llvm::SmallDenseMap<SectionKey, OutputSection *> Map;
+  std::vector<OutputSection *> &OutputSections;
 };
 
 template <class ELFT> uint64_t getHeaderSize() {
@@ -190,17 +158,17 @@ template <class ELFT> uint64_t getHeader
 }
 
 template <class ELFT> uint8_t Out<ELFT>::First;
-template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
-template <class ELFT> OutputSection<ELFT> *Out<ELFT>::BssRelRo;
-template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
+template <class ELFT> OutputSection *Out<ELFT>::Bss;
+template <class ELFT> OutputSection *Out<ELFT>::BssRelRo;
+template <class ELFT> OutputSection *Out<ELFT>::Opd;
 template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
 template <class ELFT> PhdrEntry *Out<ELFT>::TlsPhdr;
-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;
+template <class ELFT> OutputSection *Out<ELFT>::DebugInfo;
+template <class ELFT> OutputSection *Out<ELFT>::ElfHeader;
+template <class ELFT> OutputSection *Out<ELFT>::ProgramHeaders;
+template <class ELFT> OutputSection *Out<ELFT>::PreinitArray;
+template <class ELFT> OutputSection *Out<ELFT>::InitArray;
+template <class ELFT> OutputSection *Out<ELFT>::FiniArray;
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Feb 24 09:07:30 2017
@@ -485,7 +485,7 @@ template <class ELFT> static void addCop
   // See if this symbol is in a read-only segment. If so, preserve the symbol's
   // memory protection by reserving space in the .bss.rel.ro section.
   bool IsReadOnly = isReadOnly(SS);
-  OutputSection<ELFT> *OSec = IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
+  OutputSection *OSec = IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
 
   // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc.
   auto *ISec =
@@ -866,7 +866,7 @@ template <class ELFT> void scanRelocatio
 // offsets.
 // This may invalidate any output section offsets stored outside of InputSection
 template <class ELFT>
-static void mergeThunks(OutputSection<ELFT> *OS,
+static void mergeThunks(OutputSection *OS,
                         std::vector<ThunkSection<ELFT> *> &Thunks) {
   // Order Thunks in ascending OutSecOff
   auto ThunkCmp = [](const ThunkSection<ELFT> *A, const ThunkSection<ELFT> *B) {
@@ -893,7 +893,7 @@ static void mergeThunks(OutputSection<EL
              Thunks.end(), std::back_inserter(Tmp), MergeCmp);
   OS->Sections = std::move(Tmp);
   OS->Size = 0;
-  OS->assignOffsets();
+  OS->assignOffsets<ELFT>();
 }
 
 // Process all relocations from the InputSections that have been assigned
@@ -907,14 +907,13 @@ static void mergeThunks(OutputSection<EL
 // FIXME: All Thunks are assumed to be in range of the relocation. Range
 // extension Thunks are not yet supported.
 template <class ELFT>
-void createThunks(ArrayRef<OutputSectionBase *> OutputSections) {
+void createThunks(ArrayRef<OutputSection *> OutputSections) {
   // Track Symbols that already have a Thunk
   DenseMap<SymbolBody *, Thunk<ELFT> *> ThunkedSymbols;
   // Track InputSections that have a ThunkSection placed in front
   DenseMap<InputSection *, ThunkSection<ELFT> *> ThunkedSections;
   // Track the ThunksSections that need to be inserted into an OutputSection
-  std::map<OutputSection<ELFT> *, std::vector<ThunkSection<ELFT> *>>
-      ThunkSections;
+  std::map<OutputSection *, std::vector<ThunkSection<ELFT> *>> ThunkSections;
 
   // Find or create a Thunk for Body for relocation Type
   auto GetThunk = [&](SymbolBody &Body, uint32_t Type) {
@@ -925,11 +924,11 @@ void createThunks(ArrayRef<OutputSection
   };
 
   // Find or create a ThunkSection to be placed immediately before IS
-  auto GetISThunkSec = [&](InputSection *IS, OutputSection<ELFT> *OS) {
+  auto GetISThunkSec = [&](InputSection *IS, OutputSection *OS) {
     ThunkSection<ELFT> *TS = ThunkedSections.lookup(IS);
     if (TS)
       return TS;
-    auto *TOS = cast<OutputSection<ELFT>>(IS->OutSec);
+    auto *TOS = cast<OutputSection>(IS->OutSec);
     TS = make<ThunkSection<ELFT>>(TOS, IS->OutSecOff);
     ThunkSections[OS].push_back(TS);
     ThunkedSections[IS] = TS;
@@ -937,7 +936,7 @@ void createThunks(ArrayRef<OutputSection
   };
   // Find or create a ThunkSection to be placed as last executable section in
   // OS.
-  auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection<ELFT> *OS) {
+  auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection *OS) {
     if (TS == nullptr) {
       uint32_t Off = 0;
       for (auto *IS : OS->Sections) {
@@ -956,8 +955,8 @@ void createThunks(ArrayRef<OutputSection
   // We separate the creation of ThunkSections from the insertion of the
   // ThunkSections back into the OutputSection as ThunkSections are not always
   // inserted into the same OutputSection as the caller.
-  for (OutputSectionBase *Base : OutputSections) {
-    auto *OS = dyn_cast<OutputSection<ELFT>>(Base);
+  for (OutputSection *Base : OutputSections) {
+    auto *OS = dyn_cast<OutputSection>(Base);
     if (OS == nullptr)
       continue;
 
@@ -997,9 +996,9 @@ template void scanRelocations<ELF32BE>(I
 template void scanRelocations<ELF64LE>(InputSectionBase &);
 template void scanRelocations<ELF64BE>(InputSectionBase &);
 
-template void createThunks<ELF32LE>(ArrayRef<OutputSectionBase *>);
-template void createThunks<ELF32BE>(ArrayRef<OutputSectionBase *>);
-template void createThunks<ELF64LE>(ArrayRef<OutputSectionBase *>);
-template void createThunks<ELF64BE>(ArrayRef<OutputSectionBase *>);
+template void createThunks<ELF32LE>(ArrayRef<OutputSection *>);
+template void createThunks<ELF32BE>(ArrayRef<OutputSection *>);
+template void createThunks<ELF64LE>(ArrayRef<OutputSection *>);
+template void createThunks<ELF64BE>(ArrayRef<OutputSection *>);
 }
 }

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Fri Feb 24 09:07:30 2017
@@ -17,7 +17,7 @@ namespace elf {
 class SymbolBody;
 class InputSection;
 class InputSectionBase;
-class OutputSectionBase;
+class OutputSection;
 
 // List of target-independent relocation types. Relocations read
 // from files are converted to these types so that the main code
@@ -112,7 +112,7 @@ struct Relocation {
 template <class ELFT> void scanRelocations(InputSectionBase &);
 
 template <class ELFT>
-void createThunks(ArrayRef<OutputSectionBase *> OutputSections);
+void createThunks(ArrayRef<OutputSection *> OutputSections);
 
 // Return a int64_t to make sure we get the sign extension out of the way as
 // early as possible.

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Feb 24 09:07:30 2017
@@ -397,7 +397,7 @@ SymbolTable<ELFT>::addRegular(StringRef
 
 template <typename ELFT>
 Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
-                                        const OutputSectionBase *Section,
+                                        const OutputSection *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=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Fri Feb 24 09:07:30 2017
@@ -19,7 +19,6 @@
 namespace lld {
 namespace elf {
 class Lazy;
-class OutputSectionBase;
 struct Symbol;
 
 // SymbolTable is a bucket of all known symbols, including defined,
@@ -62,8 +61,8 @@ public:
                      uintX_t Value, uintX_t Size, uint8_t Binding,
                      InputSectionBase *Section, InputFile *File);
 
-  Symbol *addSynthetic(StringRef N, const OutputSectionBase *Section,
-                       uintX_t Value, uint8_t StOther);
+  Symbol *addSynthetic(StringRef N, const OutputSection *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=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Feb 24 09:07:30 2017
@@ -35,7 +35,7 @@ static typename ELFT::uint getSymVA(cons
   switch (Body.kind()) {
   case SymbolBody::DefinedSyntheticKind: {
     auto &D = cast<DefinedSynthetic>(Body);
-    const OutputSectionBase *Sec = D.Section;
+    const OutputSection *Sec = D.Section;
     if (!Sec)
       return D.Value;
     if (D.Value == uintX_t(-1))
@@ -62,7 +62,7 @@ static typename ELFT::uint getSymVA(cons
       Offset += Addend;
       Addend = 0;
     }
-    const OutputSectionBase *OutSec = IS->getOutputSection<ELFT>();
+    const OutputSection *OutSec = IS->getOutputSection<ELFT>();
     uintX_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset<ELFT>(Offset);
     if (D.isTls() && !Config->Relocatable) {
       if (!Out<ELFT>::TlsPhdr)

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Feb 24 09:07:30 2017
@@ -30,8 +30,7 @@ class BitcodeFile;
 class InputFile;
 class LazyObjectFile;
 template <class ELFT> class ObjectFile;
-template <class ELFT> class OutputSection;
-class OutputSectionBase;
+class OutputSection;
 template <class ELFT> class SharedFile;
 
 struct Symbol;
@@ -219,8 +218,7 @@ template <class ELFT> InputSectionBase *
 // If Section is null, this symbol is relative to the image base.
 class DefinedSynthetic : public Defined {
 public:
-  DefinedSynthetic(StringRef Name, uint64_t Value,
-                   const OutputSectionBase *Section)
+  DefinedSynthetic(StringRef Name, uint64_t Value, const OutputSection *Section)
       : Defined(SymbolBody::DefinedSyntheticKind, Name, /*IsLocal=*/false,
                 llvm::ELF::STV_HIDDEN, 0 /* Type */),
         Value(Value), Section(Section) {}
@@ -230,7 +228,7 @@ public:
   }
 
   uint64_t Value;
-  const OutputSectionBase *Section;
+  const OutputSection *Section;
 };
 
 class Undefined : public SymbolBody {

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Feb 24 09:07:30 2017
@@ -769,7 +769,7 @@ template <class ELFT>
 typename MipsGotSection<ELFT>::uintX_t
 MipsGotSection<ELFT>::getPageEntryOffset(const SymbolBody &B,
                                          int64_t Addend) const {
-  const OutputSectionBase *OutSec =
+  const OutputSection *OutSec =
       cast<DefinedRegular<ELFT>>(&B)
           ->Section->template getOutputSection<ELFT>();
   uintX_t SecAddr = getMipsPageAddr(OutSec->Addr);
@@ -827,7 +827,7 @@ unsigned MipsGotSection<ELFT>::getLocalE
 
 template <class ELFT> void MipsGotSection<ELFT>::finalize() {
   PageEntriesNum = 0;
-  for (std::pair<const OutputSectionBase *, size_t> &P : PageIndexMap) {
+  for (std::pair<const OutputSection *, size_t> &P : PageIndexMap) {
     // For each output section referenced by GOT page relocations calculate
     // and save into PageIndexMap an upper bound of MIPS GOT entries required
     // to store page addresses of local symbols. We assume the worst case -
@@ -877,7 +877,7 @@ template <class ELFT> void MipsGotSectio
   P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31);
   Buf += HeaderEntriesNum * sizeof(uintX_t);
   // Write 'page address' entries to the local part of the GOT.
-  for (std::pair<const OutputSectionBase *, size_t> &L : PageIndexMap) {
+  for (std::pair<const OutputSection *, size_t> &L : PageIndexMap) {
     size_t PageCount = getMipsPageCount(L.first->Size);
     uintX_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
     for (size_t PI = 0; PI < PageCount; ++PI) {
@@ -1381,7 +1381,7 @@ void SymbolTableSection<ELFT>::writeLoca
       ESym->st_shndx = SHN_ABS;
       ESym->st_value = Body.Value;
     } else {
-      const OutputSectionBase *OutSec = Section->getOutputSection<ELFT>();
+      const OutputSection *OutSec = Section->getOutputSection<ELFT>();
       ESym->st_shndx = OutSec->SectionIndex;
       ESym->st_value = OutSec->Addr + Section->getOffset(Body);
     }
@@ -1412,7 +1412,7 @@ void SymbolTableSection<ELFT>::writeGlob
     ESym->setVisibility(Body->symbol()->Visibility);
     ESym->st_value = Body->getVA<ELFT>();
 
-    if (const OutputSectionBase *OutSec = getOutputSection(Body)) {
+    if (const OutputSection *OutSec = getOutputSection(Body)) {
       ESym->st_shndx = OutSec->SectionIndex;
     } else if (isa<DefinedRegular<ELFT>>(Body)) {
       ESym->st_shndx = SHN_ABS;
@@ -1439,7 +1439,7 @@ void SymbolTableSection<ELFT>::writeGlob
 }
 
 template <class ELFT>
-const OutputSectionBase *
+const OutputSection *
 SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
   switch (Sym->kind()) {
   case SymbolBody::DefinedSyntheticKind:
@@ -2173,7 +2173,7 @@ ARMExidxSentinelSection<ELFT>::ARMExidxS
 template <class ELFT>
 void ARMExidxSentinelSection<ELFT>::writeTo(uint8_t *Buf) {
   // Get the InputSection before us, we are by definition last
-  auto RI = cast<OutputSection<ELFT>>(this->OutSec)->Sections.rbegin();
+  auto RI = cast<OutputSection>(this->OutSec)->Sections.rbegin();
   InputSection *LE = *(++RI);
   InputSection *LC = cast<InputSection>(LE->template getLinkOrderDep<ELFT>());
   uint64_t S = LC->OutSec->Addr +
@@ -2184,7 +2184,7 @@ void ARMExidxSentinelSection<ELFT>::writ
 }
 
 template <class ELFT>
-ThunkSection<ELFT>::ThunkSection(OutputSectionBase *OS, uint64_t Off)
+ThunkSection<ELFT>::ThunkSection(OutputSection *OS, uint64_t Off)
     : SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
                              sizeof(typename ELFT::uint), ".text.thunk") {
   this->OutSec = OS;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Feb 24 09:07:30 2017
@@ -249,7 +249,7 @@ private:
   uint32_t PageEntriesNum = 0;
   // Map output sections referenced by MIPS GOT relocations
   // to the first index of "Page" entries allocated for this section.
-  llvm::SmallMapVector<const OutputSectionBase *, size_t, 16> PageIndexMap;
+  llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap;
 
   typedef std::pair<const SymbolBody *, uintX_t> GotEntry;
   typedef std::vector<GotEntry> GotEntries;
@@ -364,13 +364,13 @@ class DynamicSection final : public Synt
   struct Entry {
     int32_t Tag;
     union {
-      OutputSectionBase *OutSec;
+      OutputSection *OutSec;
       InputSection *InSec;
       uint64_t Val;
       const SymbolBody *Sym;
     };
     enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
-    Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
+    Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr)
         : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
     Entry(int32_t Tag, InputSection *Sec)
         : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
@@ -443,7 +443,7 @@ public:
 
   ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
 
-  static const OutputSectionBase *getOutputSection(SymbolBody *Sym);
+  static const OutputSection *getOutputSection(SymbolBody *Sym);
 
 private:
   void writeLocalSymbols(uint8_t *&Buf);
@@ -777,7 +777,7 @@ public:
 template <class ELFT> class ThunkSection : public SyntheticSection<ELFT> {
 public:
   // ThunkSection in OS, with desired OutSecOff of Off
-  ThunkSection(OutputSectionBase *OS, uint64_t Off);
+  ThunkSection(OutputSection *OS, uint64_t Off);
 
   // Add a newly created Thunk to this container:
   // Thunk is given offset from start of this InputSection

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Feb 24 09:07:30 2017
@@ -65,7 +65,7 @@ template <class ELFT> static std::string
     if (!IS || !IS->OutSec)
       continue;
 
-    uint8_t *ISLoc = cast<OutputSection<ELFT>>(IS->OutSec)->Loc + IS->OutSecOff;
+    uint8_t *ISLoc = cast<OutputSection>(IS->OutSec)->Loc + IS->OutSecOff;
     if (ISLoc <= Loc && Loc < ISLoc + IS->template getSize<ELFT>())
       return IS->template getLocation<ELFT>(Loc - ISLoc) + ": ";
   }

Modified: lld/trunk/ELF/Thunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.h (original)
+++ lld/trunk/ELF/Thunks.h Fri Feb 24 09:07:30 2017
@@ -16,7 +16,6 @@ namespace lld {
 namespace elf {
 class SymbolBody;
 template <class ELFT> class ThunkSection;
-class OutputSectionBase;
 // Class to describe an instance of a Thunk.
 // A Thunk is a code-sequence inserted by the linker in between a caller and
 // the callee. The relocation to the callee is redirected to the Thunk, which

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Feb 24 09:07:30 2017
@@ -77,14 +77,14 @@ private:
 
   std::unique_ptr<FileOutputBuffer> Buffer;
 
-  std::vector<OutputSectionBase *> OutputSections;
+  std::vector<OutputSection *> OutputSections;
   OutputSectionFactory<ELFT> Factory{OutputSections};
 
   void addRelIpltSymbols();
   void addStartEndSymbols();
-  void addStartStopSymbols(OutputSectionBase *Sec);
+  void addStartStopSymbols(OutputSection *Sec);
   uintX_t getEntryAddr();
-  OutputSectionBase *findSection(StringRef Name);
+  OutputSection *findSection(StringRef Name);
 
   std::vector<PhdrEntry> Phdrs;
 
@@ -313,18 +313,18 @@ template <class ELFT> void Writer<ELFT>:
 
   // Create singleton output sections.
   Out<ELFT>::Bss =
-      make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
-  Out<ELFT>::BssRelRo = make<OutputSection<ELFT>>(".bss.rel.ro", SHT_NOBITS,
-                                                  SHF_ALLOC | SHF_WRITE);
+      make<OutputSection>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+  Out<ELFT>::BssRelRo =
+      make<OutputSection>(".bss.rel.ro", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
   In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
   In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
   In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
       Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
   In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
 
-  Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC);
+  Out<ELFT>::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
   Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr);
-  Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC);
+  Out<ELFT>::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
   Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
 
   if (needsInterpSection<ELFT>()) {
@@ -529,13 +529,10 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
   // Create one STT_SECTION symbol for each output section we might
   // have a relocation with.
-  for (OutputSectionBase *Sec : OutputSections) {
-    InputSectionBase *First = nullptr;
-    Sec->forEachInputSection([&](InputSectionBase *D) {
-      if (!First)
-        First = D;
-    });
-    auto *IS = dyn_cast_or_null<InputSection>(First);
+  for (OutputSection *Sec : OutputSections) {
+    InputSection *IS = nullptr;
+    if (!Sec->Sections.empty())
+      IS = Sec->Sections[0];
     if (!IS || isa<SyntheticSection<ELFT>>(IS) || IS->Type == SHT_REL ||
         IS->Type == SHT_RELA)
       continue;
@@ -565,7 +562,7 @@ static int getPPC64SectionRank(StringRef
 
 // All sections with SHF_MIPS_GPREL flag should be grouped together
 // because data in these sections is addressable with a gp relative address.
-static int getMipsSectionRank(const OutputSectionBase *S) {
+static int getMipsSectionRank(const OutputSection *S) {
   if ((S->Flags & SHF_MIPS_GPREL) == 0)
     return 0;
   if (S->Name == ".got")
@@ -579,7 +576,7 @@ static int getMipsSectionRank(const Outp
 //
 // This function returns true if a section needs to be put into a
 // PT_GNU_RELRO segment.
-template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
+template <class ELFT> bool elf::isRelroSection(const OutputSection *Sec) {
   if (!Config->ZRelro)
     return false;
 
@@ -609,8 +606,8 @@ template <class ELFT> bool elf::isRelroS
 }
 
 template <class ELFT>
-static bool compareSectionsNonScript(const OutputSectionBase *A,
-                                     const OutputSectionBase *B) {
+static bool compareSectionsNonScript(const OutputSection *A,
+                                     const OutputSection *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->Name == ".interp";
@@ -707,8 +704,7 @@ static bool compareSectionsNonScript(con
 
 // Output section ordering is determined by this function.
 template <class ELFT>
-static bool compareSections(const OutputSectionBase *A,
-                            const OutputSectionBase *B) {
+static bool compareSections(const OutputSection *A, const OutputSection *B) {
   // For now, put sections mentioned in a linker script first.
   int AIndex = Script<ELFT>::X->getSectionIndex(A->Name);
   int BIndex = Script<ELFT>::X->getSectionIndex(B->Name);
@@ -729,7 +725,7 @@ PhdrEntry::PhdrEntry(unsigned Type, unsi
   p_flags = Flags;
 }
 
-void PhdrEntry::add(OutputSectionBase *Sec) {
+void PhdrEntry::add(OutputSection *Sec) {
   Last = Sec;
   if (!First)
     First = Sec;
@@ -740,7 +736,7 @@ void PhdrEntry::add(OutputSectionBase *S
 
 template <class ELFT>
 static DefinedSynthetic *
-addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
+addOptionalSynthetic(StringRef Name, OutputSection *Sec,
                      typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) {
   if (SymbolBody *S = Symtab<ELFT>::X->find(Name))
     if (!S->isInCurrentDSO())
@@ -862,20 +858,20 @@ 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 *S) {
+template <class ELFT> static void sortInitFini(OutputSection *S) {
   if (S)
-    reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini();
+    reinterpret_cast<OutputSection *>(S)->sortInitFini();
 }
 
 // Sort input sections by the special rule for .ctors and .dtors.
-template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) {
+template <class ELFT> static void sortCtorsDtors(OutputSection *S) {
   if (S)
-    reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
+    reinterpret_cast<OutputSection *>(S)->sortCtorsDtors();
 }
 
 // Sort input sections using the list provided by --symbol-ordering-file.
 template <class ELFT>
-static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) {
+static void sortBySymbolsOrder(ArrayRef<OutputSection *> OutputSections) {
   if (Config->SymbolOrderingFile.empty())
     return;
 
@@ -900,8 +896,8 @@ static void sortBySymbolsOrder(ArrayRef<
   }
 
   // Sort sections by priority.
-  for (OutputSectionBase *Base : OutputSections)
-    if (auto *Sec = dyn_cast<OutputSection<ELFT>>(Base))
+  for (OutputSection *Base : OutputSections)
+    if (auto *Sec = dyn_cast<OutputSection>(Base))
       Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
 }
 
@@ -933,13 +929,12 @@ template <class ELFT> void Writer<ELFT>:
   sortCtorsDtors<ELFT>(findSection(".ctors"));
   sortCtorsDtors<ELFT>(findSection(".dtors"));
 
-  for (OutputSectionBase *Sec : OutputSections)
-    Sec->assignOffsets();
+  for (OutputSection *Sec : OutputSections)
+    Sec->assignOffsets<ELFT>();
 }
 
 template <class ELFT>
-static bool canSharePtLoad(const OutputSectionBase &S1,
-                           const OutputSectionBase &S2) {
+static bool canSharePtLoad(const OutputSection &S1, const OutputSection &S2) {
   if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC))
     return false;
 
@@ -995,12 +990,12 @@ template <class ELFT> void Writer<ELFT>:
   auto I = OutputSections.begin();
   auto E = OutputSections.end();
   auto NonScriptI =
-      std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) {
+      std::find_if(OutputSections.begin(), E, [](OutputSection *S) {
         return Script<ELFT>::X->getSectionIndex(S->Name) == INT_MAX;
       });
   while (NonScriptI != E) {
     auto BestPos = std::max_element(
-        I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) {
+        I, NonScriptI, [&](OutputSection *&A, OutputSection *&B) {
           bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *A);
           bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *B);
           if (ACanSharePtLoad != BCanSharePtLoad)
@@ -1036,7 +1031,7 @@ finalizeSynthetic(const std::vector<Synt
     if (SS && SS->OutSec && !SS->empty()) {
       SS->finalize();
       SS->OutSec->Size = 0;
-      SS->OutSec->assignOffsets();
+      SS->OutSec->template assignOffsets<ELFT>();
     }
 }
 
@@ -1045,7 +1040,7 @@ finalizeSynthetic(const std::vector<Synt
 // required to be in output. For example we don't need dynamic section content
 // sometimes. This function filters out such unused sections from output.
 template <class ELFT>
-static void removeUnusedSyntheticSections(std::vector<OutputSectionBase *> &V) {
+static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) {
   // All input synthetic sections that can be empty are placed after
   // all regular ones. We iterate over them all and exit at first
   // non-synthetic.
@@ -1056,7 +1051,7 @@ static void removeUnusedSyntheticSection
     if (!SS->empty() || !SS->OutSec)
       continue;
 
-    OutputSection<ELFT> *OutSec = cast<OutputSection<ELFT>>(SS->OutSec);
+    OutputSection *OutSec = cast<OutputSection>(SS->OutSec);
     OutSec->Sections.erase(
         std::find(OutSec->Sections.begin(), OutSec->Sections.end(), SS));
     // If there is no other sections in output section, remove it from output.
@@ -1077,7 +1072,7 @@ template <class ELFT> void Writer<ELFT>:
   // addresses of each section by section name. Add such symbols.
   if (!Config->Relocatable) {
     addStartEndSymbols();
-    for (OutputSectionBase *Sec : OutputSections)
+    for (OutputSection *Sec : OutputSections)
       addStartStopSymbols(Sec);
   }
 
@@ -1140,7 +1135,7 @@ template <class ELFT> void Writer<ELFT>:
   Out<ELFT>::ElfHeader->SectionIndex = 1;
 
   unsigned I = 1;
-  for (OutputSectionBase *Sec : OutputSections) {
+  for (OutputSection *Sec : OutputSections) {
     Sec->SectionIndex = I++;
     Sec->ShName = In<ELFT>::ShStrTab->addString(Sec->Name);
   }
@@ -1164,8 +1159,8 @@ 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 *Sec : OutputSections)
-    Sec->finalize();
+  for (OutputSection *Sec : OutputSections)
+    Sec->finalize<ELFT>();
 
   // Dynamic section must be the last one in this list and dynamic
   // symbol table section (DynSymTab) must be the first one.
@@ -1182,9 +1177,9 @@ template <class ELFT> void Writer<ELFT>:
 
 template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
   // Add BSS sections.
-  auto Add = [=](OutputSection<ELFT> *Sec) {
+  auto Add = [=](OutputSection *Sec) {
     if (!Sec->Sections.empty()) {
-      Sec->assignOffsets();
+      Sec->assignOffsets<ELFT>();
       OutputSections.push_back(Sec);
     }
   };
@@ -1193,7 +1188,7 @@ template <class ELFT> void Writer<ELFT>:
 
   // ARM ABI requires .ARM.exidx to be terminated by some piece of data.
   // We have the terminater synthetic section class. Add that at the end.
-  auto *OS = dyn_cast_or_null<OutputSection<ELFT>>(findSection(".ARM.exidx"));
+  auto *OS = dyn_cast_or_null<OutputSection>(findSection(".ARM.exidx"));
   if (OS && !OS->Sections.empty() && !Config->Relocatable)
     OS->addSection(make<ARMExidxSentinelSection<ELFT>>());
 }
@@ -1201,7 +1196,7 @@ 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 *OS) {
+  auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
     // These symbols resolve to the image base if the section does not exist.
     // A special value -1 indicates end of the section.
     addOptionalSynthetic<ELFT>(Start, OS, 0);
@@ -1213,7 +1208,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 *Sec = findSection(".ARM.exidx"))
+  if (OutputSection *Sec = findSection(".ARM.exidx"))
     Define("__exidx_start", "__exidx_end", Sec);
 }
 
@@ -1223,7 +1218,7 @@ 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 *Sec) {
+void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
   StringRef S = Sec->Name;
   if (!isValidCIdentifier(S))
     return;
@@ -1231,15 +1226,14 @@ void Writer<ELFT>::addStartStopSymbols(O
   addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT);
 }
 
-template <class ELFT>
-OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) {
-  for (OutputSectionBase *Sec : OutputSections)
+template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef Name) {
+  for (OutputSection *Sec : OutputSections)
     if (Sec->Name == Name)
       return Sec;
   return nullptr;
 }
 
-template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) {
+template <class ELFT> static bool needsPtLoad(OutputSection *Sec) {
   if (!(Sec->Flags & SHF_ALLOC))
     return false;
 
@@ -1277,13 +1271,13 @@ template <class ELFT> std::vector<PhdrEn
   AddHdr(PT_PHDR, PF_R)->add(Out<ELFT>::ProgramHeaders);
 
   // PT_INTERP must be the second entry if exists.
-  if (OutputSectionBase *Sec = findSection(".interp"))
+  if (OutputSection *Sec = findSection(".interp"))
     AddHdr(PT_INTERP, Sec->getPhdrFlags())->add(Sec);
 
   // Add the first PT_LOAD segment for regular output sections.
   uintX_t Flags = computeFlags<ELFT>(PF_R);
   PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
-  for (OutputSectionBase *Sec : OutputSections) {
+  for (OutputSection *Sec : OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
     if (!needsPtLoad<ELFT>(Sec))
@@ -1305,7 +1299,7 @@ template <class ELFT> std::vector<PhdrEn
 
   // Add a TLS segment if any.
   PhdrEntry TlsHdr(PT_TLS, PF_R);
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     if (Sec->Flags & SHF_TLS)
       TlsHdr.add(Sec);
   if (TlsHdr.First)
@@ -1319,7 +1313,7 @@ template <class ELFT> std::vector<PhdrEn
   // PT_GNU_RELRO includes all sections that should be marked as
   // read-only by dynamic linker after proccessing relocations.
   PhdrEntry RelRo(PT_GNU_RELRO, PF_R);
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     if (needsPtLoad<ELFT>(Sec) && isRelroSection<ELFT>(Sec))
       RelRo.add(Sec);
   if (RelRo.First)
@@ -1333,7 +1327,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 *Sec = findSection(".openbsd.randomdata"))
+  if (OutputSection *Sec = findSection(".openbsd.randomdata"))
     AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags())->add(Sec);
 
   // PT_GNU_STACK is a special section to tell the loader to make the
@@ -1356,7 +1350,7 @@ template <class ELFT> std::vector<PhdrEn
 
   // Create one PT_NOTE per a group of contiguous .note sections.
   PhdrEntry *Note = nullptr;
-  for (OutputSectionBase *Sec : OutputSections) {
+  for (OutputSection *Sec : OutputSections) {
     if (Sec->Type == SHT_NOTE) {
       if (!Note || Script<ELFT>::X->hasLMA(Sec->Name))
         Note = AddHdr(PT_NOTE, PF_R);
@@ -1374,7 +1368,7 @@ void Writer<ELFT>::addPtArmExid(std::vec
     return;
   auto I = std::find_if(
       OutputSections.begin(), OutputSections.end(),
-      [](OutputSectionBase *Sec) { return Sec->Type == SHT_ARM_EXIDX; });
+      [](OutputSection *Sec) { return Sec->Type == SHT_ARM_EXIDX; });
   if (I == OutputSections.end())
     return;
 
@@ -1403,7 +1397,7 @@ template <class ELFT> void Writer<ELFT>:
     auto I = std::find(OutputSections.begin(), End, P.Last);
     if (I == End || (I + 1) == End)
       continue;
-    OutputSectionBase *Sec = *(I + 1);
+    OutputSection *Sec = *(I + 1);
     if (needsPtLoad<ELFT>(Sec))
       Sec->PageAlign = true;
   }
@@ -1411,7 +1405,7 @@ template <class ELFT> void Writer<ELFT>:
 
 template <class ELFT>
 bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
-                          ArrayRef<OutputSectionBase *> OutputSections,
+                          ArrayRef<OutputSection *> OutputSections,
                           uint64_t Min) {
   auto FirstPTLoad =
       std::find_if(Phdrs.begin(), Phdrs.end(),
@@ -1440,7 +1434,7 @@ bool elf::allocateHeaders(std::vector<Ph
     return true;
 
   if (FirstPTLoad->First)
-    for (OutputSectionBase *Sec : OutputSections)
+    for (OutputSection *Sec : OutputSections)
       if (Sec->FirstInPtLoad == FirstPTLoad->First)
         Sec->FirstInPtLoad = Out<ELFT>::ElfHeader;
   FirstPTLoad->First = Out<ELFT>::ElfHeader;
@@ -1474,7 +1468,7 @@ template <class ELFT> void Writer<ELFT>:
   if (AllocateHeader)
     VA += getHeaderSize<ELFT>();
   uintX_t ThreadBssOffset = 0;
-  for (OutputSectionBase *Sec : OutputSections) {
+  for (OutputSection *Sec : OutputSections) {
     uintX_t Alignment = Sec->Addralign;
     if (Sec->PageAlign)
       Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
@@ -1502,8 +1496,8 @@ 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 *Sec) {
-  OutputSectionBase *First = Sec->FirstInPtLoad;
+static uintX_t getFileAlignment(uintX_t Off, OutputSection *Sec) {
+  OutputSection *First = Sec->FirstInPtLoad;
   // If the section is not in a PT_LOAD, we just have to align it.
   if (!First)
     return alignTo(Off, Sec->Addralign);
@@ -1519,7 +1513,7 @@ static uintX_t getFileAlignment(uintX_t
 }
 
 template <class ELFT, class uintX_t>
-static uintX_t setOffset(OutputSectionBase *Sec, uintX_t Off) {
+static uintX_t setOffset(OutputSection *Sec, uintX_t Off) {
   if (Sec->Type == SHT_NOBITS) {
     Sec->Offset = Off;
     return Off;
@@ -1532,7 +1526,7 @@ static uintX_t setOffset(OutputSectionBa
 
 template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
   uintX_t Off = 0;
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     if (Sec->Flags & SHF_ALLOC)
       Off = setOffset<ELFT>(Sec, Off);
   FileSize = alignTo(Off, sizeof(uintX_t));
@@ -1544,7 +1538,7 @@ template <class ELFT> void Writer<ELFT>:
   Off = setOffset<ELFT>(Out<ELFT>::ElfHeader, Off);
   Off = setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off);
 
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     Off = setOffset<ELFT>(Sec, Off);
 
   SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
@@ -1555,8 +1549,8 @@ template <class ELFT> void Writer<ELFT>:
 // file offsets and VAs to all sections.
 template <class ELFT> void Writer<ELFT>::setPhdrs() {
   for (PhdrEntry &P : Phdrs) {
-    OutputSectionBase *First = P.First;
-    OutputSectionBase *Last = P.Last;
+    OutputSection *First = P.First;
+    OutputSection *Last = P.Last;
     if (First) {
       P.p_filesz = Last->Offset - First->Offset;
       if (Last->Type != SHT_NOBITS)
@@ -1604,7 +1598,7 @@ template <class ELFT> typename ELFT::uin
     return Addr;
 
   // Case 4
-  if (OutputSectionBase *Sec = findSection(".text")) {
+  if (OutputSection *Sec = findSection(".text")) {
     if (Config->WarnMissingEntry)
       warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
            utohexstr(Sec->Addr));
@@ -1636,8 +1630,8 @@ static uint16_t getELFType() {
 // to each section. This function fixes some predefined
 // symbol values that depend on section address and size.
 template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
-  auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2,
-                OutputSectionBase *Sec, uint64_t Value) {
+  auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2, OutputSection *Sec,
+                uint64_t Value) {
     if (S1) {
       S1->Section = Sec;
       S1->Value = Value;
@@ -1679,7 +1673,7 @@ template <class ELFT> void Writer<ELFT>:
       // Find GP-relative section with the lowest address
       // and use this address to calculate default _gp value.
       uintX_t Gp = -1;
-      for (const OutputSectionBase * OS : OutputSections)
+      for (const OutputSection *OS : OutputSections)
         if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp)
           Gp = OS->Addr;
       if (Gp != (uintX_t)-1)
@@ -1742,7 +1736,7 @@ 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 *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     Sec->writeHeaderTo<ELFT>(++SHdrs);
 }
 
@@ -1796,9 +1790,9 @@ template <class ELFT> void Writer<ELFT>:
 
 template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
   uint8_t *Buf = Buffer->getBufferStart();
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     if (Sec->Flags & SHF_ALLOC)
-      Sec->writeTo(Buf + Sec->Offset);
+      Sec->writeTo<ELFT>(Buf + Sec->Offset);
 }
 
 // Write section contents to a mmap'ed file.
@@ -1810,28 +1804,28 @@ template <class ELFT> void Writer<ELFT>:
   Out<ELFT>::Opd = findSection(".opd");
   if (Out<ELFT>::Opd) {
     Out<ELFT>::OpdBuf = Buf + Out<ELFT>::Opd->Offset;
-    Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset);
+    Out<ELFT>::Opd->template writeTo<ELFT>(Buf + Out<ELFT>::Opd->Offset);
   }
 
-  OutputSectionBase *EhFrameHdr =
+  OutputSection *EhFrameHdr =
       In<ELFT>::EhFrameHdr ? In<ELFT>::EhFrameHdr->OutSec : nullptr;
 
   // In -r or -emit-relocs mode, write the relocation sections first as in
   // ELf_Rel targets we might find out that we need to modify the relocated
   // section while doing it.
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
-      Sec->writeTo(Buf + Sec->Offset);
+      Sec->writeTo<ELFT>(Buf + Sec->Offset);
 
-  for (OutputSectionBase *Sec : OutputSections)
+  for (OutputSection *Sec : OutputSections)
     if (Sec != Out<ELFT>::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL &&
         Sec->Type != SHT_RELA)
-      Sec->writeTo(Buf + Sec->Offset);
+      Sec->writeTo<ELFT>(Buf + Sec->Offset);
 
   // The .eh_frame_hdr depends on .eh_frame section contents, therefore
   // it should be written after .eh_frame is written.
   if (EhFrameHdr)
-    EhFrameHdr->writeTo(Buf + EhFrameHdr->Offset);
+    EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
 }
 
 template <class ELFT> void Writer<ELFT>::writeBuildId() {
@@ -1850,19 +1844,19 @@ template void elf::writeResult<ELF64LE>(
 template void elf::writeResult<ELF64BE>();
 
 template bool elf::allocateHeaders<ELF32LE>(std::vector<PhdrEntry> &,
-                                            ArrayRef<OutputSectionBase *>,
+                                            ArrayRef<OutputSection *>,
                                             uint64_t);
 template bool elf::allocateHeaders<ELF32BE>(std::vector<PhdrEntry> &,
-                                            ArrayRef<OutputSectionBase *>,
+                                            ArrayRef<OutputSection *>,
                                             uint64_t);
 template bool elf::allocateHeaders<ELF64LE>(std::vector<PhdrEntry> &,
-                                            ArrayRef<OutputSectionBase *>,
+                                            ArrayRef<OutputSection *>,
                                             uint64_t);
 template bool elf::allocateHeaders<ELF64BE>(std::vector<PhdrEntry> &,
-                                            ArrayRef<OutputSectionBase *>,
+                                            ArrayRef<OutputSection *>,
                                             uint64_t);
 
-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 bool elf::isRelroSection<ELF32LE>(const OutputSection *);
+template bool elf::isRelroSection<ELF32BE>(const OutputSection *);
+template bool elf::isRelroSection<ELF64LE>(const OutputSection *);
+template bool elf::isRelroSection<ELF64BE>(const OutputSection *);

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=296127&r1=296126&r2=296127&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Fri Feb 24 09:07:30 2017
@@ -18,20 +18,20 @@
 namespace lld {
 namespace elf {
 class InputFile;
-class OutputSectionBase;
+class OutputSection;
 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 *Sec);
+template <class ELFT> bool isRelroSection(const OutputSection *Sec);
 
 // This describes a program header entry.
 // Each contains type, access flags and range of output sections that will be
 // placed in it.
 struct PhdrEntry {
   PhdrEntry(unsigned Type, unsigned Flags);
-  void add(OutputSectionBase *Sec);
+  void add(OutputSection *Sec);
 
   uint64_t p_paddr = 0;
   uint64_t p_vaddr = 0;
@@ -42,16 +42,16 @@ struct PhdrEntry {
   uint32_t p_type = 0;
   uint32_t p_flags = 0;
 
-  OutputSectionBase *First = nullptr;
-  OutputSectionBase *Last = nullptr;
+  OutputSection *First = nullptr;
+  OutputSection *Last = nullptr;
   bool HasLMA = false;
 };
 
 llvm::StringRef getOutputSectionName(llvm::StringRef Name);
 
 template <class ELFT>
-bool allocateHeaders(std::vector<PhdrEntry> &,
-                     llvm::ArrayRef<OutputSectionBase *>, uint64_t Min);
+bool allocateHeaders(std::vector<PhdrEntry> &, llvm::ArrayRef<OutputSection *>,
+                     uint64_t Min);
 
 template <class ELFT> uint32_t getMipsEFlags();
 




More information about the llvm-commits mailing list