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
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;
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
/// \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, ...) \
#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)...)
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
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!");
}
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
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;
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;
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:
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));
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
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:
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
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