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.

llvm-svn: 286414
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 7ca4399..bc4f81a 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -42,10 +42,8 @@
 // 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 @@
     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 @@
 
   uint32_t getPhdrFlags() const;
 
-  void updateAlignment(uintX_t Alignment) {
+  void updateAlignment(uint64_t Alignment) {
     if (Alignment > Addralign)
       Addralign = Alignment;
   }
@@ -97,7 +95,7 @@
   // 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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
       : 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 @@
   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 @@
 };
 
 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 @@
   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 @@
 // 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 @@
 // 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 @@
 // 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 @@
   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 @@
   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 @@
   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 @@
   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 @@
 };
 
 // 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 @@
   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 @@
 };
 
 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 @@
   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 @@
   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 @@
   // 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 @@
   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 @@
   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 @@
   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 @@
 // 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 @@
   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 @@
   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 @@
   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> 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> 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