Removes createELFFile which takes a template class as a template parameter.

This patch is to reduce amount of template uses. The new code is less
exciting and boring than before, but I think it is easier to read.

Differential Revision: https://reviews.llvm.org/D32467

llvm-svn: 301488
This commit is contained in:
Rui Ueyama 2017-04-26 22:51:51 +00:00
parent 87b30ac9d3
commit 330e52b018
3 changed files with 57 additions and 57 deletions

View File

@ -137,15 +137,13 @@ std::string lld::toString(const InputFile *F) {
return F->ToStringCache; return F->ToStringCache;
} }
template <class ELFT> static ELFKind getELFKind() {
if (ELFT::TargetEndianness == support::little)
return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
}
template <class ELFT> template <class ELFT>
ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) { ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
EKind = getELFKind<ELFT>(); if (ELFT::TargetEndianness == support::little)
EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
else
EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
EMachine = getObj().getHeader()->e_machine; EMachine = getObj().getHeader()->e_machine;
OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI]; OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
} }
@ -174,8 +172,10 @@ void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
} }
template <class ELFT> template <class ELFT>
elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M, StringRef ArchiveName)
: ELFFileBase<ELFT>(Base::ObjectKind, M) {} : ELFFileBase<ELFT>(Base::ObjectKind, M) {
this->ArchiveName = ArchiveName;
}
template <class ELFT> template <class ELFT>
ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() { ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
@ -862,49 +862,24 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this)); Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
} }
// Small bit of template meta programming to handle the SharedFile constructor static ELFKind getELFKind(MemoryBufferRef MB) {
// being the only one with a DefaultSoName parameter.
template <template <class> class T, class E>
typename std::enable_if<std::is_same<T<E>, SharedFile<E>>::value,
InputFile *>::type
createELFAux(MemoryBufferRef MB, StringRef DefaultSoName) {
return make<T<E>>(MB, DefaultSoName);
}
template <template <class> class T, class E>
typename std::enable_if<!std::is_same<T<E>, SharedFile<E>>::value,
InputFile *>::type
createELFAux(MemoryBufferRef MB, StringRef DefaultSoName) {
return make<T<E>>(MB);
}
template <template <class> class T>
static InputFile *createELFFile(MemoryBufferRef MB, StringRef DefaultSoName) {
unsigned char Size; unsigned char Size;
unsigned char Endian; unsigned char Endian;
std::tie(Size, Endian) = getElfArchType(MB.getBuffer()); std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB) if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
fatal(MB.getBufferIdentifier() + ": invalid data encoding"); fatal(MB.getBufferIdentifier() + ": invalid data encoding");
if (Size != ELFCLASS32 && Size != ELFCLASS64)
fatal(MB.getBufferIdentifier() + ": invalid file class");
size_t BufSize = MB.getBuffer().size(); size_t BufSize = MB.getBuffer().size();
if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) || if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
(Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr))) (Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
fatal(MB.getBufferIdentifier() + ": file is too short"); fatal(MB.getBufferIdentifier() + ": file is too short");
InputFile *Obj; if (Size == ELFCLASS32)
if (Size == ELFCLASS32 && Endian == ELFDATA2LSB) return (Endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
Obj = createELFAux<T, ELF32LE>(MB, DefaultSoName); return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB)
Obj = createELFAux<T, ELF32BE>(MB, DefaultSoName);
else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB)
Obj = createELFAux<T, ELF64LE>(MB, DefaultSoName);
else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB)
Obj = createELFAux<T, ELF64BE>(MB, DefaultSoName);
else
fatal(MB.getBufferIdentifier() + ": invalid file class");
if (!Config->FirstElf)
Config->FirstElf = Obj;
return Obj;
} }
template <class ELFT> void BinaryFile::parse() { template <class ELFT> void BinaryFile::parse() {
@ -941,15 +916,36 @@ static bool isBitcode(MemoryBufferRef MB) {
InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
uint64_t OffsetInArchive) { uint64_t OffsetInArchive) {
InputFile *F = isBitcode(MB) if (isBitcode(MB))
? make<BitcodeFile>(MB, ArchiveName, OffsetInArchive) return make<BitcodeFile>(MB, ArchiveName, OffsetInArchive);
: createELFFile<ObjectFile>(MB, "");
F->ArchiveName = ArchiveName; switch (getELFKind(MB)) {
return F; case ELF32LEKind:
return make<ObjectFile<ELF32LE>>(MB, ArchiveName);
case ELF32BEKind:
return make<ObjectFile<ELF32BE>>(MB, ArchiveName);
case ELF64LEKind:
return make<ObjectFile<ELF64LE>>(MB, ArchiveName);
case ELF64BEKind:
return make<ObjectFile<ELF64BE>>(MB, ArchiveName);
default:
llvm_unreachable("getELFKind");
}
} }
InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) { InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) {
return createELFFile<SharedFile>(MB, DefaultSoName); switch (getELFKind(MB)) {
case ELF32LEKind:
return make<SharedFile<ELF32LE>>(MB, DefaultSoName);
case ELF32BEKind:
return make<SharedFile<ELF32BE>>(MB, DefaultSoName);
case ELF64LEKind:
return make<SharedFile<ELF64LE>>(MB, DefaultSoName);
case ELF64BEKind:
return make<SharedFile<ELF64BE>>(MB, DefaultSoName);
default:
llvm_unreachable("getELFKind");
}
} }
MemoryBufferRef LazyObjectFile::getBuffer() { MemoryBufferRef LazyObjectFile::getBuffer() {
@ -1004,17 +1000,18 @@ std::vector<StringRef> LazyObjectFile::getSymbols() {
if (isBitcode(this->MB)) if (isBitcode(this->MB))
return getBitcodeSymbols(); return getBitcodeSymbols();
unsigned char Size; switch (getELFKind(this->MB)) {
unsigned char Endian; case ELF32LEKind:
std::tie(Size, Endian) = getElfArchType(this->MB.getBuffer()); return getElfSymbols<ELF32LE>();
if (Size == ELFCLASS32) { case ELF32BEKind:
if (Endian == ELFDATA2LSB)
return getElfSymbols<ELF32LE>();
return getElfSymbols<ELF32BE>(); return getElfSymbols<ELF32BE>();
} case ELF64LEKind:
if (Endian == ELFDATA2LSB)
return getElfSymbols<ELF64LE>(); return getElfSymbols<ELF64LE>();
return getElfSymbols<ELF64BE>(); case ELF64BEKind:
return getElfSymbols<ELF64BE>();
default:
llvm_unreachable("getELFKind");
}
} }
template void ArchiveFile::parse<ELF32LE>(); template void ArchiveFile::parse<ELF32LE>();

View File

@ -156,7 +156,7 @@ public:
ArrayRef<SymbolBody *> getSymbols(); ArrayRef<SymbolBody *> getSymbols();
ArrayRef<SymbolBody *> getLocalSymbols(); ArrayRef<SymbolBody *> getLocalSymbols();
explicit ObjectFile(MemoryBufferRef M); ObjectFile(MemoryBufferRef M, StringRef ArchiveName);
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
InputSectionBase *getSection(const Elf_Sym &Sym) const; InputSectionBase *getSection(const Elf_Sym &Sym) const;

View File

@ -52,6 +52,9 @@ template <class ELFT> static bool isCompatible(InputFile *F) {
// Add symbols in File to the symbol table. // Add symbols in File to the symbol table.
template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File))
Config->FirstElf = File;
if (!isCompatible<ELFT>(File)) if (!isCompatible<ELFT>(File))
return; return;