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

View File

@ -156,7 +156,7 @@ public:
ArrayRef<SymbolBody *> getSymbols();
ArrayRef<SymbolBody *> getLocalSymbols();
explicit ObjectFile(MemoryBufferRef M);
ObjectFile(MemoryBufferRef M, StringRef ArchiveName);
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
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.
template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File))
Config->FirstElf = File;
if (!isCompatible<ELFT>(File))
return;