ELF2: Simplify Writer interface.

We are using Writer more like a function instead of a class.
This patch makes it a function to simplify the interface.
All details of Writer class is now hidden from other parts of the linker.

llvm-svn: 244169
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 9964630..ab4fc2e 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -7,8 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Driver.h"
 #include "Config.h"
+#include "Driver.h"
+#include "InputFiles.h"
+#include "SymbolTable.h"
 #include "Writer.h"
 #include "llvm/ADT/STLExtras.h"
 
@@ -116,25 +118,17 @@
   // Write the result.
   ObjectFileBase &FirstObj = *Symtab.ObjectFiles[0];
   switch (FirstObj.kind()) {
-  case InputFile::Object32LEKind: {
-    Writer<object::ELF32LE> Out(&Symtab);
-    Out.write(Config->OutputFile);
+  case InputFile::Object32LEKind:
+    writeResult<object::ELF32LE>(&Symtab, Config->OutputFile);
     return;
-  }
-  case InputFile::Object32BEKind: {
-    Writer<object::ELF32BE> Out(&Symtab);
-    Out.write(Config->OutputFile);
+  case InputFile::Object32BEKind:
+    writeResult<object::ELF32BE>(&Symtab, Config->OutputFile);
     return;
-  }
-  case InputFile::Object64LEKind: {
-    Writer<object::ELF64LE> Out(&Symtab);
-    Out.write(Config->OutputFile);
+  case InputFile::Object64LEKind:
+    writeResult<object::ELF64LE>(&Symtab, Config->OutputFile);
     return;
-  }
-  case InputFile::Object64BEKind: {
-    Writer<object::ELF64BE> Out(&Symtab);
-    Out.write(Config->OutputFile);
+  case InputFile::Object64BEKind:
+    writeResult<object::ELF64BE>(&Symtab, Config->OutputFile);
     return;
   }
-  }
 }
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 63dfec3..b7bfd46 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -7,10 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Writer.h"
 #include "Chunks.h"
 #include "Driver.h"
+#include "SymbolTable.h"
+#include "Writer.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/FileOutputBuffer.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
@@ -21,13 +23,77 @@
 
 static const int PageSize = 4096;
 
+namespace {
+// The writer writes a SymbolTable result to a file.
+template <class ELFT> class Writer {
+public:
+  typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
+  Writer(SymbolTable *T, StringRef S) : Symtab(T), OutputPath(S) {}
+  void run();
+
+private:
+  void createSections();
+  void assignAddresses();
+  void openFile(StringRef OutputPath);
+  void writeHeader();
+  void writeSections();
+
+  SymbolTable *Symtab;
+  StringRef OutputPath;
+  std::unique_ptr<llvm::FileOutputBuffer> Buffer;
+  llvm::SpecificBumpPtrAllocator<OutputSection> CAlloc;
+  std::vector<OutputSection *> OutputSections;
+
+  uint64_t FileSize;
+  uint64_t SizeOfHeaders;
+  uintX_t SectionHeaderOff;
+
+  std::vector<std::unique_ptr<Chunk>> Chunks;
+};
+} // anonymous namespace
+
+namespace lld {
+namespace elf2 {
+
+// OutputSection represents a section in an output file. It's a
+// container of chunks. OutputSection and Chunk are 1:N relationship.
+// Chunks cannot belong to more than one OutputSections. The writer
+// creates multiple OutputSections and assign them unique,
+// non-overlapping file offsets and VAs.
+class OutputSection {
+public:
+  OutputSection(StringRef Name) : Name(Name), Header({}) {}
+  void setVA(uint64_t);
+  void setFileOffset(uint64_t);
+  template <class ELFT> void addSectionChunk(SectionChunk<ELFT> *C);
+  std::vector<Chunk *> &getChunks() { return Chunks; }
+  template <class ELFT>
+  void writeHeaderTo(llvm::object::Elf_Shdr_Impl<ELFT> *SHdr);
+
+  // Returns the size of the section in the output file.
+  uint64_t getSize() { return Header.sh_size; }
+
+private:
+  StringRef Name;
+  llvm::ELF::Elf64_Shdr Header;
+  std::vector<Chunk *> Chunks;
+};
+
 template <class ELFT>
-Writer<ELFT>::Writer(SymbolTable *Symtab)
-    : Symtab(Symtab) {}
-template <class ELFT> Writer<ELFT>::~Writer() {}
+void writeResult(SymbolTable *Symtab, StringRef Path) {
+  Writer<ELFT>(Symtab, Path).run();
+}
+
+template void writeResult<ELF32LE>(SymbolTable *, StringRef);
+template void writeResult<ELF32BE>(SymbolTable *, StringRef);
+template void writeResult<ELF64LE>(SymbolTable *, StringRef);
+template void writeResult<ELF64BE>(SymbolTable *, StringRef);
+
+} // namespace elf2
+} // namespace lld
 
 // The main function of the writer.
-template <class ELFT> void Writer<ELFT>::write(StringRef OutputPath) {
+template <class ELFT> void Writer<ELFT>::run() {
   createSections();
   assignAddresses();
   openFile(OutputPath);
@@ -171,17 +237,3 @@
       C->writeTo(Buf);
   }
 }
-
-namespace lld {
-namespace elf2 {
-template class Writer<ELF32LE>;
-template class Writer<ELF32BE>;
-template class Writer<ELF64LE>;
-template class Writer<ELF64BE>;
-
-template void OutputSection::addSectionChunk<ELF32LE>(SectionChunk<ELF32LE> *);
-template void OutputSection::addSectionChunk<ELF32BE>(SectionChunk<ELF32BE> *);
-template void OutputSection::addSectionChunk<ELF64LE>(SectionChunk<ELF64LE> *);
-template void OutputSection::addSectionChunk<ELF64BE>(SectionChunk<ELF64BE> *);
-}
-}
diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h
index 1feb68b..5302d6b 100644
--- a/lld/ELF/Writer.h
+++ b/lld/ELF/Writer.h
@@ -10,65 +10,16 @@
 #ifndef LLD_ELF_WRITER_H
 #define LLD_ELF_WRITER_H
 
-#include "Chunks.h"
-#include "SymbolTable.h"
-#include "llvm/Support/FileOutputBuffer.h"
-
 namespace lld {
 namespace elf2 {
-// OutputSection represents a section in an output file. It's a
-// container of chunks. OutputSection and Chunk are 1:N relationship.
-// Chunks cannot belong to more than one OutputSections. The writer
-// creates multiple OutputSections and assign them unique,
-// non-overlapping file offsets and VAs.
-class OutputSection {
-public:
-  OutputSection(StringRef Name) : Name(Name), Header({}) {}
-  void setVA(uint64_t);
-  void setFileOffset(uint64_t);
-  template <class ELFT> void addSectionChunk(SectionChunk<ELFT> *C);
-  std::vector<Chunk *> &getChunks() { return Chunks; }
-  template <class ELFT>
-  void writeHeaderTo(llvm::object::Elf_Shdr_Impl<ELFT> *SHdr);
 
-  // Returns the size of the section in the output file.
-  uint64_t getSize() { return Header.sh_size; }
+class OutputSection;
+class SymbolTable;
 
-private:
-  StringRef Name;
-  llvm::ELF::Elf64_Shdr Header;
-  std::vector<Chunk *> Chunks;
-};
+template <class ELFT>
+void writeResult(SymbolTable *Symtab, StringRef Path);
 
-// The writer writes a SymbolTable result to a file.
-template <class ELFT> class Writer {
-public:
-  typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
-
-  explicit Writer(SymbolTable *Symtab);
-  ~Writer();
-  void write(StringRef Path);
-
-private:
-  void createSections();
-  void assignAddresses();
-  void openFile(StringRef OutputPath);
-  void writeHeader();
-  void writeSections();
-
-  SymbolTable *Symtab;
-  std::unique_ptr<llvm::FileOutputBuffer> Buffer;
-  llvm::SpecificBumpPtrAllocator<OutputSection> CAlloc;
-  std::vector<OutputSection *> OutputSections;
-
-  uint64_t FileSize;
-  uint64_t SizeOfHeaders;
-  uintX_t SectionHeaderOff;
-
-  std::vector<std::unique_ptr<Chunk>> Chunks;
-};
-
-} // namespace elf2
-} // namespace lld
+}
+}
 
 #endif