[ELF2] Devirtualize SymbolBody.
llvm-svn: 243496
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 2ab8fa2..8db2064 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -65,7 +65,7 @@
StringRef Name = *NameOrErr;
if (Sym->isUndefined())
return new (Alloc) Undefined(Name);
- return new (Alloc) DefinedRegular<ELFT>(Name);
+ return new (Alloc) DefinedRegular<ELFT>(this, Sym);
}
namespace lld {
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 9b3bc30..35bc499 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -9,12 +9,30 @@
#include "Symbols.h"
#include "Chunks.h"
+#include "InputFiles.h"
using namespace llvm::object;
using namespace lld;
using namespace lld::elf2;
+template <class ELFT>
+StringRef
+getSymbolName(const llvm::object::ELFFile<ELFT> *F,
+ const typename llvm::object::ELFFile<ELFT>::Elf_Sym *S) {
+ ErrorOr<StringRef> StrTab = F->getStringTableForSymtab(*F->getDotSymtabSec());
+ if (!StrTab || S->st_name >= StrTab->size())
+ llvm::report_fatal_error("Invalid string table.");
+ return StrTab->data() + S->st_name;
+}
+
+template <class ELFT>
+DefinedRegular<ELFT>::DefinedRegular(ObjectFile<ELFT> *F, const Elf_Sym *S)
+ : Defined(DefinedRegularKind, getSymbolName<ELFT>(F->getObj(), S)), File(F),
+ Sym(S) {
+ IsExternal = S->isExternal();
+}
+
// Returns 1, 0 or -1 if this symbol should take precedence
// over the Other, tie or lose, respectively.
int SymbolBody::compare(SymbolBody *Other) {
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 7ae51cd..2018fd6 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -21,6 +21,7 @@
class Chunk;
class InputFile;
class SymbolBody;
+template <class ELFT> class ObjectFile;
// A real symbol object, SymbolBody, is usually accessed indirectly
// through a Symbol. There's always one Symbol for each symbol name.
@@ -40,14 +41,13 @@
UndefinedKind,
};
- Kind kind() const { return SymbolKind; }
- virtual ~SymbolBody() {}
+ Kind kind() const { return static_cast<Kind>(SymbolKind); }
// Returns true if this is an external symbol.
- virtual bool isExternal() { return true; }
+ bool isExternal() const { return true; }
// Returns the symbol name.
- virtual StringRef getName() = 0;
+ StringRef getName() const { return Name; }
// A SymbolBody has a backreference to a Symbol. Originally they are
// doubly-linked. A backreference will never change. But the pointer
@@ -64,10 +64,13 @@
int compare(SymbolBody *Other);
protected:
- SymbolBody(Kind K) : SymbolKind(K) {}
+ SymbolBody(Kind K, StringRef N = "")
+ : SymbolKind(K), IsExternal(true), Name(N) {}
-private:
- const Kind SymbolKind;
+protected:
+ const unsigned SymbolKind : 8;
+ unsigned IsExternal : 1;
+ StringRef Name;
Symbol *Backref = nullptr;
};
@@ -75,7 +78,7 @@
// etc.
class Defined : public SymbolBody {
public:
- Defined(Kind K) : SymbolBody(K) {}
+ Defined(Kind K, StringRef N = "") : SymbolBody(K, N) {}
static bool classof(const SymbolBody *S) {
Kind K = S->kind();
@@ -85,31 +88,28 @@
// Regular defined symbols read from object file symbol tables.
template <class ELFT> class DefinedRegular : public Defined {
+ typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
+
public:
- DefinedRegular(StringRef Name) : Defined(DefinedRegularKind), Name(Name) {}
+ DefinedRegular(ObjectFile<ELFT> *F, const Elf_Sym *S);
static bool classof(const SymbolBody *S) {
return S->kind() == DefinedRegularKind;
}
- StringRef getName() override { return Name; }
-
private:
- StringRef Name;
+ ObjectFile<ELFT> *File;
+ const Elf_Sym *Sym;
};
// Undefined symbols.
class Undefined : public SymbolBody {
public:
- explicit Undefined(StringRef N) : SymbolBody(UndefinedKind), Name(N) {}
+ explicit Undefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
static bool classof(const SymbolBody *S) {
return S->kind() == UndefinedKind;
}
- StringRef getName() override { return Name; }
-
-private:
- StringRef Name;
};
} // namespace elf2