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

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 10 15:47:25 PST 2016


It seems we could do the same thing for InputSectionBase, and it would have
the same advantage as this patch aims for. What do you think?

On Wed, Nov 9, 2016 at 3:23 PM, Rafael Espindola via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> 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/InputSecti
> on.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/LinkerScri
> pt.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/LinkerScri
> pt.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/OutputSect
> ions.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/OutputSect
> ions.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/SymbolTabl
> e.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/SymbolTabl
> e.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.cp
> p?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;
>  };
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161110/f60fc0dc/attachment-0001.html>


More information about the llvm-commits mailing list