ELF: Pass file types instead of type traits to ELFObjectReader.
authorRui Ueyama <ruiu@google.com>
Fri, 3 Apr 2015 20:29:37 +0000 (20:29 +0000)
committerRui Ueyama <ruiu@google.com>
Fri, 3 Apr 2015 20:29:37 +0000 (20:29 +0000)
All <Arch>ELFFileCreateFileTraits structs are the same except its file type.
That means that we don't need to pass the type traits. Instead, we can only
pass file types. By doing this, we can remove copy-pasted boilerplates.

llvm-svn: 234047

lld/lib/ReaderWriter/ELF/AArch64/AArch64ELFReader.h
lld/lib/ReaderWriter/ELF/ARM/ARMELFReader.h
lld/lib/ReaderWriter/ELF/CreateELF.h
lld/lib/ReaderWriter/ELF/DynamicFile.h
lld/lib/ReaderWriter/ELF/ELFReader.h
lld/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h
lld/lib/ReaderWriter/ELF/Mips/MipsELFReader.h
lld/lib/ReaderWriter/ELF/X86/X86ELFReader.h
lld/lib/ReaderWriter/ELF/X86_64/X86_64ELFReader.h

index f22329f..025b027 100644 (file)
@@ -19,16 +19,8 @@ class AArch64LinkingContext;
 
 typedef llvm::object::ELFType<llvm::support::little, 2, true> AArch64ELFType;
 
-struct AArch64ELFFileCreateELFTraits {
-  template <class ELFT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, AArch64LinkingContext &ctx) {
-    return lld::elf::ELFFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
-typedef ELFObjectReader<AArch64ELFType, AArch64ELFFileCreateELFTraits,
-                        AArch64LinkingContext> AArch64ELFObjectReader;
+typedef ELFObjectReader<AArch64ELFType, AArch64LinkingContext,
+                        lld::elf::ELFFile> AArch64ELFObjectReader;
 
 typedef ELFDSOReader<AArch64ELFType, AArch64LinkingContext> AArch64ELFDSOReader;
 
index 82714bd..299fe28 100644 (file)
@@ -18,16 +18,8 @@ namespace elf {
 
 typedef llvm::object::ELFType<llvm::support::little, 2, false> ARMELFType;
 
-struct ARMELFFileCreateELFTraits {
-  template <class ELFT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, ARMLinkingContext &ctx) {
-    return lld::elf::ARMELFFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
-typedef ELFObjectReader<ARMELFType, ARMELFFileCreateELFTraits,
-                        ARMLinkingContext> ARMELFObjectReader;
+typedef ELFObjectReader<ARMELFType, ARMLinkingContext, lld::elf::ARMELFFile>
+    ARMELFObjectReader;
 typedef ELFDSOReader<ARMELFType, ARMLinkingContext> ARMELFDSOReader;
 
 } // namespace elf
index 3ef28b2..5047a8f 100644 (file)
@@ -36,8 +36,7 @@ using llvm::object::ELFType;
 /// \param args arguments forwarded to CreateELFTraits<T>::create.
 
 #define LLVM_CREATE_ELF_CreateELFTraits(endian, align, is64, ...) \
-  Traits::template create<ELFType<llvm::support::endian, align, is64>>( \
-      __VA_ARGS__);
+  new FileT<ELFType<llvm::support::endian, align, is64>>(__VA_ARGS__);
 
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
 # define LLVM_CREATE_ELF_Create(normal, low, endian, is64, ...) \
@@ -50,15 +49,16 @@ using llvm::object::ELFType;
 #else
 # define LLVM_CREATE_ELF_Create(normal, low, endian, is64, ...) \
   if (maxAlignment >= low) \
-    return LLVM_CREATE_ELF_CreateELFTraits(endian, low, is64, __VA_ARGS__) \
+    file = LLVM_CREATE_ELF_CreateELFTraits(endian, low, is64, __VA_ARGS__) \
   else \
     llvm_unreachable("Invalid alignment for ELF file!");
 #endif
 
-template <class Traits, class... Args>
+template <template <typename ELFT> class FileT, class... Args>
 llvm::ErrorOr<std::unique_ptr<lld::File>>
 createELF(std::pair<unsigned char, unsigned char> ident,
           std::size_t maxAlignment, Args &&... args) {
+  lld::File *file = nullptr;
   if (ident.first == llvm::ELF::ELFCLASS32 &&
       ident.second == llvm::ELF::ELFDATA2LSB) {
     LLVM_CREATE_ELF_Create(4, 2, little, false, std::forward<Args>(args)...)
@@ -72,8 +72,11 @@ createELF(std::pair<unsigned char, unsigned char> ident,
              ident.second == llvm::ELF::ELFDATA2LSB) {
     LLVM_CREATE_ELF_Create(8, 2, little, true, std::forward<Args>(args)...)
   }
-  llvm_unreachable("Invalid ELF type!");
+  if (!file)
+    llvm_unreachable("Invalid ELF type!");
+  return std::unique_ptr<lld::File>(file);
 }
+
 } // end anon namespace
 
 #undef LLVM_CREATE_ELF_CreateELFTraits
index e3e898f..50c37c6 100644 (file)
@@ -24,6 +24,10 @@ public:
   static ErrorOr<std::unique_ptr<DynamicFile>>
   create(std::unique_ptr<llvm::MemoryBuffer> mb, ELFLinkingContext &ctx);
 
+  DynamicFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
+      : SharedLibraryFile(mb->getBufferIdentifier()), _mb(std::move(mb)),
+        _ctx(ctx), _useShlibUndefines(ctx.useShlibUndefines()) {}
+
   const SharedLibraryAtom *exports(StringRef name,
                                    bool dataSymbolOnly) const override {
     assert(!dataSymbolOnly && "Invalid option for ELF exports!");
@@ -89,10 +93,6 @@ protected:
   }
 
 private:
-  DynamicFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
-      : SharedLibraryFile(mb->getBufferIdentifier()), _mb(std::move(mb)),
-        _ctx(ctx), _useShlibUndefines(ctx.useShlibUndefines()) {}
-
   mutable llvm::BumpPtrAllocator _alloc;
   std::unique_ptr<llvm::object::ELFFile<ELFT>> _objFile;
   /// \brief DT_SONAME
index 2980072..ad16a09 100644 (file)
@@ -18,7 +18,7 @@
 namespace lld {
 namespace elf {
 
-template <typename ELFT, typename ELFTraitsT, typename ContextT>
+template <typename ELFT, typename ContextT, template <typename> class FileT>
 class ELFObjectReader : public Reader {
 public:
   typedef llvm::object::Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
@@ -36,8 +36,7 @@ public:
            std::vector<std::unique_ptr<File>> &result) const override {
     std::size_t maxAlignment =
         1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
-    auto f =
-        createELF<ELFTraitsT>(llvm::object::getElfArchType(mb->getBuffer()),
+    auto f = createELF<FileT>(llvm::object::getElfArchType(mb->getBuffer()),
                               maxAlignment, std::move(mb), _ctx);
     if (std::error_code ec = f.getError())
       return ec;
@@ -55,14 +54,6 @@ protected:
   ContextT &_ctx;
 };
 
-struct DynamicFileCreateELFTraits {
-  template <typename ELFT, typename ContextT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, ContextT &ctx) {
-    return DynamicFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
 template <typename ELFT, typename ContextT>
 class ELFDSOReader : public Reader {
 public:
@@ -81,9 +72,9 @@ public:
            std::vector<std::unique_ptr<File>> &result) const override {
     std::size_t maxAlignment =
         1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
-    auto f = createELF<DynamicFileCreateELFTraits>(
-        llvm::object::getElfArchType(mb->getBuffer()),
-        maxAlignment, std::move(mb), _ctx);
+    auto f =
+        createELF<DynamicFile>(llvm::object::getElfArchType(mb->getBuffer()),
+                               maxAlignment, std::move(mb), _ctx);
     if (std::error_code ec = f.getError())
       return ec;
     result.push_back(std::move(*f));
index 11af36d..8706eca 100644 (file)
@@ -18,16 +18,8 @@ namespace elf {
 
 typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
 
-struct HexagonELFFileCreateELFTraits {
-  template <class ELFT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, HexagonLinkingContext &ctx) {
-    return lld::elf::HexagonELFFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
-typedef ELFObjectReader<HexagonELFType, HexagonELFFileCreateELFTraits,
-                        HexagonLinkingContext> HexagonELFObjectReader;
+typedef ELFObjectReader<HexagonELFType, HexagonLinkingContext,
+                        lld::elf::HexagonELFFile> HexagonELFObjectReader;
 typedef ELFDSOReader<HexagonELFType, HexagonLinkingContext> HexagonELFDSOReader;
 
 } // namespace elf
index 1d0189b..d69479e 100644 (file)
 namespace lld {
 namespace elf {
 
-struct MipsELFFileCreateTraits {
-  template <class ELFT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, MipsLinkingContext &ctx) {
-    return lld::elf::MipsELFFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
 template <class ELFT>
 class MipsELFObjectReader
-    : public ELFObjectReader<ELFT, MipsELFFileCreateTraits,
-                             MipsLinkingContext> {
-  typedef ELFObjectReader<ELFT, MipsELFFileCreateTraits, MipsLinkingContext>
+    : public ELFObjectReader<ELFT, MipsLinkingContext, lld::elf::MipsELFFile> {
+  typedef ELFObjectReader<ELFT, MipsLinkingContext, lld::elf::MipsELFFile>
       BaseReaderType;
 
 public:
index 5aed1fc..94a2141 100644 (file)
@@ -18,16 +18,8 @@ namespace elf {
 class X86LinkingContext;
 typedef llvm::object::ELFType<llvm::support::little, 2, false> X86ELFType;
 
-struct X86ELFFileCreateELFTraits {
-  template <class ELFT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, X86LinkingContext &ctx) {
-    return lld::elf::ELFFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
-typedef ELFObjectReader<X86ELFType, X86ELFFileCreateELFTraits,
-                        X86LinkingContext> X86ELFObjectReader;
+typedef ELFObjectReader<X86ELFType, X86LinkingContext, lld::elf::ELFFile>
+    X86ELFObjectReader;
 typedef ELFDSOReader<X86ELFType, X86LinkingContext> X86ELFDSOReader;
 
 } // namespace elf
index ea0ac8b..85e0030 100644 (file)
@@ -18,16 +18,8 @@ namespace elf {
 class X86_64LinkingContext;
 typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
 
-struct X86_64ELFFileCreateELFTraits {
-  template <class ELFT>
-  static llvm::ErrorOr<std::unique_ptr<lld::File>>
-  create(std::unique_ptr<llvm::MemoryBuffer> mb, X86_64LinkingContext &ctx) {
-    return lld::elf::ELFFile<ELFT>::create(std::move(mb), ctx);
-  }
-};
-
-typedef ELFObjectReader<X86_64ELFType, X86_64ELFFileCreateELFTraits,
-                        X86_64LinkingContext> X86_64ELFObjectReader;
+typedef ELFObjectReader<X86_64ELFType, X86_64LinkingContext, lld::elf::ELFFile>
+    X86_64ELFObjectReader;
 typedef ELFDSOReader<X86_64ELFType, X86_64LinkingContext> X86_64ELFDSOReader;
 
 } // namespace elf