[lld] r317006 - Merge SymbolBody and Symbol into one class, SymbolBody.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 31 09:07:41 PDT 2017


Author: ruiu
Date: Tue Oct 31 09:07:41 2017
New Revision: 317006

URL: http://llvm.org/viewvc/llvm-project?rev=317006&view=rev
Log:
Merge SymbolBody and Symbol into one class, SymbolBody.

SymbolBody and Symbol were separated classes due to a historical reason.
Symbol used to be a pointer to a SymbolBody, and the relationship
between Symbol and SymbolBody was n:1.

r2681780 changed that. Since that patch, SymbolBody and Symbol are
allocated next to each other to improve memory locality, and they have
1:1 relationship now. So, the separation of Symbol and SymbolBody no
longer makes sense.

This patch merges them into one class. In order to avoid updating too
many places, I chose SymbolBody as a unified name. I'll rename it Symbol
in a follow-up patch.

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

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/LTO.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/docs/NewLLD.rst

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Oct 31 09:07:41 2017
@@ -24,7 +24,6 @@ namespace lld {
 namespace elf {
 
 class InputFile;
-struct Symbol;
 
 enum ELFKind {
   ELFNoneKind,

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Oct 31 09:07:41 2017
@@ -997,13 +997,12 @@ static void excludeLibs(opt::InputArgLis
   DenseSet<StringRef> Libs = getExcludeLibs(Args);
   bool All = Libs.count("ALL");
 
-  for (InputFile *File : Files) {
+  for (InputFile *File : Files)
     if (Optional<StringRef> Archive = getArchiveName(File))
       if (All || Libs.count(path::filename(*Archive)))
-        for (SymbolBody *SymBody : File->getSymbols())
-          if (!SymBody->isLocal())
-            SymBody->symbol()->VersionId = VER_NDX_LOCAL;
-  }
+        for (SymbolBody *Sym : File->getSymbols())
+          if (!Sym->isLocal())
+            Sym->VersionId = VER_NDX_LOCAL;
 }
 
 // Do actual linking. Note that when this function is called,

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Oct 31 09:07:41 2017
@@ -551,16 +551,14 @@ SymbolBody *ObjFile<ELFT>::createSymbolB
 
   switch (Sym->st_shndx) {
   case SHN_UNDEF:
-    return Symtab
-        ->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, StOther, Type,
-                             /*CanOmitFromDynSym=*/false, this)
-        ->body();
+    return Symtab->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, StOther,
+                                      Type,
+                                      /*CanOmitFromDynSym=*/false, this);
   case SHN_COMMON:
     if (Value == 0 || Value >= UINT32_MAX)
       fatal(toString(this) + ": common symbol '" + Name +
             "' has invalid alignment: " + Twine(Value));
-    return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, this)
-        ->body();
+    return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, this);
   }
 
   switch (Binding) {
@@ -570,13 +568,11 @@ SymbolBody *ObjFile<ELFT>::createSymbolB
   case STB_WEAK:
   case STB_GNU_UNIQUE:
     if (Sec == &InputSection::Discarded)
-      return Symtab
-          ->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, StOther, Type,
-                               /*CanOmitFromDynSym=*/false, this)
-          ->body();
-    return Symtab
-        ->addRegular<ELFT>(Name, StOther, Type, Value, Size, Binding, Sec, this)
-        ->body();
+      return Symtab->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding,
+                                        StOther, Type,
+                                        /*CanOmitFromDynSym=*/false, this);
+    return Symtab->addRegular<ELFT>(Name, StOther, Type, Value, Size, Binding,
+                                    Sec, this);
   }
 }
 
@@ -587,8 +583,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr
 template <class ELFT> void ArchiveFile::parse() {
   Symbols.reserve(File->getNumberOfSymbols());
   for (const Archive::Symbol &Sym : File->symbols())
-    Symbols.push_back(
-        Symtab->addLazyArchive<ELFT>(Sym.getName(), this, Sym)->body());
+    Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), this, Sym));
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
@@ -848,9 +843,9 @@ static uint8_t mapVisibility(GlobalValue
 }
 
 template <class ELFT>
-static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
-                                   const lto::InputFile::Symbol &ObjSym,
-                                   BitcodeFile *F) {
+static SymbolBody *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
+                                       const lto::InputFile::Symbol &ObjSym,
+                                       BitcodeFile *F) {
   StringRef NameRef = Saver.save(ObjSym.getName());
   uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
 
@@ -883,8 +878,7 @@ void BitcodeFile::parse(DenseSet<CachedH
     KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second);
 
   for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
-    Symbols.push_back(
-        createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this)->body());
+    Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
 }
 
 static ELFKind getELFKind(MemoryBufferRef MB) {

Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Tue Oct 31 09:07:41 2017
@@ -108,8 +108,8 @@ static std::unique_ptr<lto::LTO> createL
 }
 
 BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {
-  for (Symbol *Sym : Symtab->getSymbols()) {
-    StringRef Name = Sym->body()->getName();
+  for (SymbolBody *Sym : Symtab->getSymbols()) {
+    StringRef Name = Sym->getName();
     for (StringRef Prefix : {"__start_", "__stop_"})
       if (Name.startswith(Prefix))
         UsedStartStop.insert(Name.substr(Prefix.size()));
@@ -118,9 +118,9 @@ BitcodeCompiler::BitcodeCompiler() : LTO
 
 BitcodeCompiler::~BitcodeCompiler() = default;
 
-static void undefine(Symbol *S) {
-  replaceBody<Undefined>(S, nullptr, S->body()->getName(), /*IsLocal=*/false,
-                         STV_DEFAULT, S->body()->Type);
+static void undefine(SymbolBody *S) {
+  replaceBody<Undefined>(S, nullptr, S->getName(), /*IsLocal=*/false,
+                         STV_DEFAULT, S->Type);
 }
 
 void BitcodeCompiler::add(BitcodeFile &F) {
@@ -136,8 +136,7 @@ void BitcodeCompiler::add(BitcodeFile &F
 
   // Provide a resolution to the LTO API for each symbol.
   for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
-    SymbolBody *B = Syms[SymNum];
-    Symbol *Sym = B->symbol();
+    SymbolBody *Sym = Syms[SymNum];
     lto::SymbolResolution &R = Resols[SymNum];
     ++SymNum;
 
@@ -146,7 +145,7 @@ void BitcodeCompiler::add(BitcodeFile &F
     // flags an undefined in IR with a definition in ASM as prevailing.
     // Once IRObjectFile is fixed to report only one symbol this hack can
     // be removed.
-    R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F;
+    R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F;
 
     // We ask LTO to preserve following global symbols:
     // 1) All symbols when doing relocatable link, so that them can be used
@@ -165,7 +164,7 @@ void BitcodeCompiler::add(BitcodeFile &F
     // still not final:
     // 1) Aliased (with --defsym) or wrapped (with --wrap) symbols.
     // 2) Symbols redefined in linker script.
-    R.LinkerRedefined = !Sym->CanInline || ScriptSymbols.count(B->getName());
+    R.LinkerRedefined = !Sym->CanInline || ScriptSymbols.count(Sym->getName());
   }
   checkError(LTOObj->add(std::move(F.Obj), Resols));
 }

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Oct 31 09:07:41 2017
@@ -127,7 +127,7 @@ void LinkerScript::addSymbol(SymbolAssig
     return;
 
   // Define a symbol.
-  Symbol *Sym;
+  SymbolBody *Sym;
   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
   std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
                                               /*CanOmitFromDynSym*/ false,
@@ -151,7 +151,7 @@ void LinkerScript::addSymbol(SymbolAssig
 
   replaceBody<DefinedRegular>(Sym, nullptr, Cmd->Name, /*IsLocal=*/false,
                               Visibility, STT_NOTYPE, SymValue, 0, Sec);
-  Cmd->Sym = cast<DefinedRegular>(Sym->body());
+  Cmd->Sym = cast<DefinedRegular>(Sym);
 }
 
 // This function is called from assignAddresses, while we are

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Tue Oct 31 09:07:41 2017
@@ -228,9 +228,9 @@ template <class ELFT> static void doGcSe
 
   // Preserve externally-visible symbols if the symbols defined by this
   // file can interrupt other ELF file's symbols at runtime.
-  for (Symbol *S : Symtab->getSymbols())
+  for (SymbolBody *S : Symtab->getSymbols())
     if (S->includeInDynsym())
-      MarkSymbol(S->body());
+      MarkSymbol(S);
 
   // Preserve special sections and those which are specified in linker
   // script KEEP command.

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Oct 31 09:07:41 2017
@@ -544,7 +544,7 @@ template <class ELFT> static void addCop
   for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
     Sym->CopyRelSec = Sec;
     Sym->IsPreemptible = false;
-    Sym->symbol()->IsUsedInRegularObj = true;
+    Sym->IsUsedInRegularObj = true;
   }
 
   In<ELFT>::RelaDyn->addReloc({Target->CopyRel, Sec, 0, false, SS, 0});
@@ -717,11 +717,11 @@ static bool maybeReportUndefined(SymbolB
   if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll)
     return false;
 
-  if (Sym.isLocal() || !Sym.isUndefined() || Sym.symbol()->isWeak())
+  if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak())
     return false;
 
-  bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL &&
-                       Sym.getVisibility() == STV_DEFAULT;
+  bool CanBeExternal =
+      Sym.computeBinding() != STB_LOCAL && Sym.getVisibility() == STV_DEFAULT;
   if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal)
     return false;
 

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Oct 31 09:07:41 2017
@@ -136,9 +136,9 @@ template <class ELFT> void SymbolTable::
 template <class ELFT>
 DefinedRegular *SymbolTable::addAbsolute(StringRef Name, uint8_t Visibility,
                                          uint8_t Binding) {
-  Symbol *Sym = addRegular<ELFT>(Name, Visibility, STT_NOTYPE, 0, 0, Binding,
-                                 nullptr, nullptr);
-  return cast<DefinedRegular>(Sym->body());
+  SymbolBody *Sym = addRegular<ELFT>(Name, Visibility, STT_NOTYPE, 0, 0,
+                                     Binding, nullptr, nullptr);
+  return cast<DefinedRegular>(Sym);
 }
 
 // Set a flag for --trace-symbol so that we can print out a log message
@@ -150,12 +150,11 @@ void SymbolTable::trace(StringRef Name)
 // Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
 // Used to implement --wrap.
 template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
-  SymbolBody *B = find(Name);
-  if (!B)
+  SymbolBody *Sym = find(Name);
+  if (!Sym)
     return;
-  Symbol *Sym = B->symbol();
-  Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
-  Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
+  SymbolBody *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
+  SymbolBody *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
 
   defsym(Real, Sym);
   defsym(Sym, Wrap);
@@ -172,7 +171,7 @@ void SymbolTable::addSymbolAlias(StringR
     return;
   }
 
-  defsym(addUndefined<ELFT>(Alias), B->symbol());
+  defsym(addUndefined<ELFT>(Alias), B);
 }
 
 // Apply symbol renames created by -wrap and -defsym. The renames are created
@@ -190,13 +189,13 @@ void SymbolTable::applySymbolRenames() {
   // __wrap_foo point to, we just want have __real_foo in the symbol table.
 
   // First make a copy of __real_foo
-  std::vector<Symbol> Origs;
+  std::vector<SymbolUnion> Origs;
   for (const auto &P : WrapSymbols)
-    Origs.push_back(*P.second);
+    Origs.emplace_back(*(SymbolUnion *)P.second);
 
   // Replace __real_foo with foo and foo with __wrap_foo
   for (SymbolRenaming &S : Defsyms) {
-    S.Dst->body()->copyFrom(S.Src->body());
+    S.Dst->copyFrom(S.Src);
     S.Dst->File = S.Src->File;
     S.Dst->Binding = S.Binding;
   }
@@ -205,16 +204,16 @@ void SymbolTable::applySymbolRenames() {
   // __real_foo into it.
   for (unsigned I = 0, N = WrapSymbols.size(); I < N; ++I) {
     // We now have two copies of __wrap_foo. Drop one.
-    Symbol *Wrap = WrapSymbols[I].first;
+    SymbolBody *Wrap = WrapSymbols[I].first;
     Wrap->IsUsedInRegularObj = false;
 
-    Symbol *Real = &Origs[I];
+    auto *Real = (SymbolBody *)&Origs[I];
     // If __real_foo was undefined, we don't want it in the symbol table.
-    if (!Real->body()->isInCurrentOutput())
+    if (!Real->isInCurrentOutput())
       continue;
 
-    auto *NewSym = make<Symbol>();
-    memcpy(NewSym, Real, sizeof(Symbol));
+    auto *NewSym = (SymbolBody *)make<SymbolUnion>();
+    memcpy(NewSym, Real, sizeof(SymbolUnion));
     SymVector.push_back(NewSym);
   }
 }
@@ -228,7 +227,7 @@ static uint8_t getMinVisibility(uint8_t
 }
 
 // Find an existing symbol or create and insert a new one.
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
+std::pair<SymbolBody *, bool> SymbolTable::insert(StringRef Name) {
   // <name>@@<version> means the symbol is the default version. In that
   // case <name>@@<version> will be used to resolve references to <name>.
   //
@@ -249,9 +248,9 @@ std::pair<Symbol *, bool> SymbolTable::i
     V = SymIndex((int)SymVector.size(), true);
   }
 
-  Symbol *Sym;
+  SymbolBody *Sym;
   if (IsNew) {
-    Sym = make<Symbol>();
+    Sym = (SymbolBody *)make<SymbolUnion>();
     Sym->InVersionScript = false;
     Sym->Binding = STB_WEAK;
     Sym->Visibility = STV_DEFAULT;
@@ -269,11 +268,11 @@ std::pair<Symbol *, bool> SymbolTable::i
 
 // Find an existing symbol or create and insert a new one, then apply the given
 // attributes.
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
-                                              uint8_t Visibility,
-                                              bool CanOmitFromDynSym,
-                                              InputFile *File) {
-  Symbol *S;
+std::pair<SymbolBody *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
+                                                  uint8_t Visibility,
+                                                  bool CanOmitFromDynSym,
+                                                  InputFile *File) {
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
@@ -286,17 +285,16 @@ std::pair<Symbol *, bool> SymbolTable::i
   if (!File || File->kind() == InputFile::ObjKind)
     S->IsUsedInRegularObj = true;
 
-  if (!WasInserted && S->body()->Type != SymbolBody::UnknownType &&
-      ((Type == STT_TLS) != S->body()->isTls())) {
-    error("TLS attribute mismatch: " + toString(*S->body()) +
-          "\n>>> defined in " + toString(S->File) + "\n>>> defined in " +
-          toString(File));
+  if (!WasInserted && S->Type != SymbolBody::UnknownType &&
+      ((Type == STT_TLS) != S->isTls())) {
+    error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " +
+          toString(S->File) + "\n>>> defined in " + toString(File));
   }
 
   return {S, WasInserted};
 }
 
-template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
+template <class ELFT> SymbolBody *SymbolTable::addUndefined(StringRef Name) {
   return addUndefined<ELFT>(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT,
                             /*Type*/ 0,
                             /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
@@ -305,30 +303,29 @@ template <class ELFT> Symbol *SymbolTabl
 static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
 
 template <class ELFT>
-Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
-                                  uint8_t StOther, uint8_t Type,
-                                  bool CanOmitFromDynSym, InputFile *File) {
-  Symbol *S;
+SymbolBody *SymbolTable::addUndefined(StringRef Name, bool IsLocal,
+                                      uint8_t Binding, uint8_t StOther,
+                                      uint8_t Type, bool CanOmitFromDynSym,
+                                      InputFile *File) {
+  SymbolBody *S;
   bool WasInserted;
   uint8_t Visibility = getVisibility(StOther);
   std::tie(S, WasInserted) =
       insert(Name, Type, Visibility, CanOmitFromDynSym, File);
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
-  if (WasInserted ||
-      (isa<SharedSymbol>(S->body()) && Visibility != STV_DEFAULT)) {
+  if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) {
     S->Binding = Binding;
     replaceBody<Undefined>(S, File, Name, IsLocal, StOther, Type);
     return S;
   }
   if (Binding != STB_WEAK) {
-    SymbolBody *B = S->body();
-    if (!B->isInCurrentOutput())
+    if (!S->isInCurrentOutput())
       S->Binding = Binding;
-    if (auto *SS = dyn_cast<SharedSymbol>(B))
+    if (auto *SS = dyn_cast<SharedSymbol>(S))
       SS->getFile<ELFT>()->IsUsed = true;
   }
-  if (auto *L = dyn_cast<Lazy>(S->body())) {
+  if (auto *L = dyn_cast<Lazy>(S)) {
     // An undefined weak will not fetch archive members. See comment on Lazy in
     // Symbols.h for the details.
     if (S->isWeak())
@@ -345,9 +342,9 @@ Symbol *SymbolTable::addUndefined(String
 // FIXME: If users can transition to using
 // .symver foo,foo@@@VER
 // we can delete this hack.
-static int compareVersion(Symbol *S, StringRef Name) {
+static int compareVersion(SymbolBody *S, StringRef Name) {
   bool A = Name.contains("@@");
-  bool B = S->body()->getName().contains("@@");
+  bool B = S->getName().contains("@@");
   if (A && !B)
     return 1;
   if (!A && B)
@@ -358,17 +355,14 @@ static int compareVersion(Symbol *S, Str
 // We have a new defined symbol with the specified binding. Return 1 if the new
 // symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
 // strong defined symbols.
-static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
+static int compareDefined(SymbolBody *S, bool WasInserted, uint8_t Binding,
                           StringRef Name) {
   if (WasInserted)
     return 1;
-  SymbolBody *Body = S->body();
-  if (!Body->isInCurrentOutput())
+  if (!S->isInCurrentOutput())
     return 1;
-
   if (int R = compareVersion(S, Name))
     return R;
-
   if (Binding == STB_WEAK)
     return -1;
   if (S->isWeak())
@@ -379,21 +373,21 @@ static int compareDefined(Symbol *S, boo
 // We have a new non-common defined symbol with the specified binding. Return 1
 // if the new symbol should win, -1 if the new symbol should lose, or 0 if there
 // is a conflict. If the new symbol wins, also update the binding.
-static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
-                                   bool IsAbsolute, uint64_t Value,
-                                   StringRef Name) {
+static int compareDefinedNonCommon(SymbolBody *S, bool WasInserted,
+                                   uint8_t Binding, bool IsAbsolute,
+                                   uint64_t Value, StringRef Name) {
   if (int Cmp = compareDefined(S, WasInserted, Binding, Name)) {
     if (Cmp > 0)
       S->Binding = Binding;
     return Cmp;
   }
-  SymbolBody *B = S->body();
-  if (isa<DefinedCommon>(B)) {
+  if (isa<DefinedCommon>(S)) {
     // Non-common symbols take precedence over common symbols.
     if (Config->WarnCommon)
-      warn("common " + S->body()->getName() + " is overridden");
+      warn("common " + S->getName() + " is overridden");
     return 1;
-  } else if (auto *R = dyn_cast<DefinedRegular>(B)) {
+  }
+  if (auto *R = dyn_cast<DefinedRegular>(S)) {
     if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
         R->Value == Value)
       return -1;
@@ -401,10 +395,11 @@ static int compareDefinedNonCommon(Symbo
   return 0;
 }
 
-Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
-                               uint8_t Binding, uint8_t StOther, uint8_t Type,
-                               InputFile *File) {
-  Symbol *S;
+SymbolBody *SymbolTable::addCommon(StringRef N, uint64_t Size,
+                                   uint32_t Alignment, uint8_t Binding,
+                                   uint8_t StOther, uint8_t Type,
+                                   InputFile *File) {
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, File);
@@ -413,16 +408,16 @@ Symbol *SymbolTable::addCommon(StringRef
     S->Binding = Binding;
     replaceBody<DefinedCommon>(S, File, N, Size, Alignment, StOther, Type);
   } else if (Cmp == 0) {
-    auto *C = dyn_cast<DefinedCommon>(S->body());
+    auto *C = dyn_cast<DefinedCommon>(S);
     if (!C) {
       // Non-common symbols take precedence over common symbols.
       if (Config->WarnCommon)
-        warn("common " + S->body()->getName() + " is overridden");
+        warn("common " + S->getName() + " is overridden");
       return S;
     }
 
     if (Config->WarnCommon)
-      warn("multiple common of " + S->body()->getName());
+      warn("multiple common of " + S->getName());
 
     Alignment = C->Alignment = std::max(C->Alignment, Alignment);
     if (Size > C->Size)
@@ -477,10 +472,11 @@ static void reportDuplicate(SymbolBody *
 }
 
 template <typename ELFT>
-Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
-                                uint64_t Value, uint64_t Size, uint8_t Binding,
-                                SectionBase *Section, InputFile *File) {
-  Symbol *S;
+SymbolBody *SymbolTable::addRegular(StringRef Name, uint8_t StOther,
+                                    uint8_t Type, uint64_t Value, uint64_t Size,
+                                    uint8_t Binding, SectionBase *Section,
+                                    InputFile *File) {
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, File);
@@ -490,8 +486,8 @@ Symbol *SymbolTable::addRegular(StringRe
     replaceBody<DefinedRegular>(S, File, Name, /*IsLocal=*/false, StOther, Type,
                                 Value, Size, Section);
   else if (Cmp == 0)
-    reportDuplicate<ELFT>(S->body(),
-                          dyn_cast_or_null<InputSectionBase>(Section), Value);
+    reportDuplicate<ELFT>(S, dyn_cast_or_null<InputSectionBase>(Section),
+                          Value);
   return S;
 }
 
@@ -502,7 +498,7 @@ void SymbolTable::addShared(StringRef Na
   // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
   // as the visibility, which will leave the visibility in the symbol table
   // unchanged.
-  Symbol *S;
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
                                     /*CanOmitFromDynSym*/ true, File);
@@ -510,11 +506,10 @@ void SymbolTable::addShared(StringRef Na
   if (Sym.getVisibility() == STV_DEFAULT)
     S->ExportDynamic = true;
 
-  SymbolBody *Body = S->body();
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
-  if (WasInserted || ((Body->isUndefined() || Body->isLazy()) &&
-                      Body->getVisibility() == STV_DEFAULT)) {
+  if (WasInserted || ((S->isUndefined() || S->isLazy()) &&
+                      S->getVisibility() == STV_DEFAULT)) {
     replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(),
                               Sym.st_value, Sym.st_size, Alignment, Verdef);
     if (!S->isWeak())
@@ -522,10 +517,10 @@ void SymbolTable::addShared(StringRef Na
   }
 }
 
-Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
-                                uint8_t StOther, uint8_t Type,
-                                bool CanOmitFromDynSym, BitcodeFile *F) {
-  Symbol *S;
+SymbolBody *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
+                                    uint8_t StOther, uint8_t Type,
+                                    bool CanOmitFromDynSym, BitcodeFile *F) {
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) =
       insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, F);
@@ -535,7 +530,7 @@ Symbol *SymbolTable::addBitcode(StringRe
     replaceBody<DefinedRegular>(S, F, Name, /*IsLocal=*/false, StOther, Type, 0,
                                 0, nullptr);
   else if (Cmp == 0)
-    reportDuplicate(S->body(), F);
+    reportDuplicate(S, F);
   return S;
 }
 
@@ -546,10 +541,10 @@ SymbolBody *SymbolTable::find(StringRef
   SymIndex V = It->second;
   if (V.Idx == -1)
     return nullptr;
-  return SymVector[V.Idx]->body();
+  return SymVector[V.Idx];
 }
 
-void SymbolTable::defsym(Symbol *Dst, Symbol *Src) {
+void SymbolTable::defsym(SymbolBody *Dst, SymbolBody *Src) {
   // We want to tell LTO not to inline Dst symbol because LTO doesn't
   // know the final symbol contents after renaming.
   Dst->CanInline = false;
@@ -561,22 +556,22 @@ void SymbolTable::defsym(Symbol *Dst, Sy
 }
 
 template <class ELFT>
-Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile *F,
-                                    const object::Archive::Symbol Sym) {
-  Symbol *S;
+SymbolBody *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile *F,
+                                        const object::Archive::Symbol Sym) {
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
     replaceBody<LazyArchive>(S, F, Sym, SymbolBody::UnknownType);
     return S;
   }
-  if (!S->body()->isUndefined())
+  if (!S->isUndefined())
     return S;
 
   // An undefined weak will not fetch archive members. See comment on Lazy in
   // Symbols.h for the details.
   if (S->isWeak()) {
-    replaceBody<LazyArchive>(S, F, Sym, S->body()->Type);
+    replaceBody<LazyArchive>(S, F, Sym, S->Type);
     return S;
   }
   std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym);
@@ -587,19 +582,19 @@ Symbol *SymbolTable::addLazyArchive(Stri
 
 template <class ELFT>
 void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
-  Symbol *S;
+  SymbolBody *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
     replaceBody<LazyObject>(S, &Obj, Name, SymbolBody::UnknownType);
     return;
   }
-  if (!S->body()->isUndefined())
+  if (!S->isUndefined())
     return;
 
   // See comment for addLazyArchive above.
   if (S->isWeak())
-    replaceBody<LazyObject>(S, &Obj, Name, S->body()->Type);
+    replaceBody<LazyObject>(S, &Obj, Name, S->Type);
   else if (InputFile *F = Obj.fetch())
     addFile<ELFT>(F);
 }
@@ -609,7 +604,7 @@ template <class ELFT> void SymbolTable::
   if (SymbolBody *B = find(Name)) {
     // Mark the symbol not to be eliminated by LTO
     // even if it is a bitcode symbol.
-    B->symbol()->IsUsedInRegularObj = true;
+    B->IsUsedInRegularObj = true;
     if (auto *L = dyn_cast_or_null<Lazy>(B))
       if (InputFile *File = L->fetch())
         addFile<ELFT>(File);
@@ -629,13 +624,13 @@ template <class ELFT> void SymbolTable::
       SymbolBody *Sym = find(U);
       if (!Sym || !Sym->isDefined())
         continue;
-      Sym->symbol()->ExportDynamic = true;
+      Sym->ExportDynamic = true;
 
       // If -dynamic-list is given, the default version is set to
       // VER_NDX_LOCAL, which prevents a symbol to be exported via .dynsym.
       // Set to VER_NDX_GLOBAL so the symbol will be handled as if it were
       // specified by -dynamic-list.
-      Sym->symbol()->VersionId = VER_NDX_GLOBAL;
+      Sym->VersionId = VER_NDX_GLOBAL;
     }
   }
 }
@@ -656,14 +651,13 @@ template <class ELFT> void SymbolTable::
 StringMap<std::vector<SymbolBody *>> &SymbolTable::getDemangledSyms() {
   if (!DemangledSyms) {
     DemangledSyms.emplace();
-    for (Symbol *Sym : SymVector) {
-      SymbolBody *B = Sym->body();
-      if (!B->isInCurrentOutput())
+    for (SymbolBody *Sym : SymVector) {
+      if (!Sym->isInCurrentOutput())
         continue;
-      if (Optional<std::string> S = demangle(B->getName()))
-        (*DemangledSyms)[*S].push_back(B);
+      if (Optional<std::string> S = demangle(Sym->getName()))
+        (*DemangledSyms)[*S].push_back(Sym);
       else
-        (*DemangledSyms)[B->getName()].push_back(B);
+        (*DemangledSyms)[Sym->getName()].push_back(Sym);
     }
   }
   return *DemangledSyms;
@@ -689,11 +683,9 @@ std::vector<SymbolBody *> SymbolTable::f
     return Res;
   }
 
-  for (Symbol *Sym : SymVector) {
-    SymbolBody *B = Sym->body();
-    if (B->isInCurrentOutput() && M.match(B->getName()))
-      Res.push_back(B);
-  }
+  for (SymbolBody *Sym : SymVector)
+    if (Sym->isInCurrentOutput() && M.match(Sym->getName()))
+      Res.push_back(Sym);
   return Res;
 }
 
@@ -722,8 +714,8 @@ void SymbolTable::handleDynamicList() {
 
     for (SymbolBody *B : Syms) {
       if (!Config->Shared)
-        B->symbol()->ExportDynamic = true;
-      else if (B->symbol()->includeInDynsym())
+        B->ExportDynamic = true;
+      else if (B->includeInDynsym())
         B->IsPreemptible = true;
     }
   }
@@ -746,14 +738,13 @@ void SymbolTable::assignExactVersion(Sym
   }
 
   // Assign the version.
-  for (SymbolBody *B : Syms) {
+  for (SymbolBody *Sym : Syms) {
     // Skip symbols containing version info because symbol versions
     // specified by symbol names take precedence over version scripts.
     // See parseSymbolVersion().
-    if (B->getName().contains('@'))
+    if (Sym->getName().contains('@'))
       continue;
 
-    Symbol *Sym = B->symbol();
     if (Sym->InVersionScript)
       warn("duplicate symbol '" + Ver.Name + "' in version script");
     Sym->VersionId = VersionId;
@@ -769,8 +760,8 @@ void SymbolTable::assignWildcardVersion(
   // so we set a version to a symbol only if no version has been assigned
   // to the symbol. This behavior is compatible with GNU.
   for (SymbolBody *B : findAllByVersion(Ver))
-    if (B->symbol()->VersionId == Config->DefaultSymbolVersion)
-      B->symbol()->VersionId = VersionId;
+    if (B->VersionId == Config->DefaultSymbolVersion)
+      B->VersionId = VersionId;
 }
 
 // This function processes version scripts by updating VersionId
@@ -801,8 +792,8 @@ void SymbolTable::scanVersionScript() {
   // Symbol themselves might know their versions because symbols
   // can contain versions in the form of <name>@<version>.
   // Let them parse and update their names to exclude version suffix.
-  for (Symbol *Sym : SymVector)
-    Sym->body()->parseSymbolVersion();
+  for (SymbolBody *Sym : SymVector)
+    Sym->parseSymbolVersion();
 }
 
 template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef);
@@ -810,23 +801,27 @@ template void SymbolTable::addSymbolWrap
 template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef);
 template void SymbolTable::addSymbolWrap<ELF64BE>(StringRef);
 
-template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef);
-template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef);
-template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef);
-template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef);
-
-template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, bool, uint8_t,
-                                                    uint8_t, uint8_t, bool,
-                                                    InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, bool, uint8_t,
-                                                    uint8_t, uint8_t, bool,
-                                                    InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, bool, uint8_t,
-                                                    uint8_t, uint8_t, bool,
-                                                    InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, bool, uint8_t,
-                                                    uint8_t, uint8_t, bool,
-                                                    InputFile *);
+template SymbolBody *SymbolTable::addUndefined<ELF32LE>(StringRef);
+template SymbolBody *SymbolTable::addUndefined<ELF32BE>(StringRef);
+template SymbolBody *SymbolTable::addUndefined<ELF64LE>(StringRef);
+template SymbolBody *SymbolTable::addUndefined<ELF64BE>(StringRef);
+
+template SymbolBody *SymbolTable::addUndefined<ELF32LE>(StringRef, bool,
+                                                        uint8_t, uint8_t,
+                                                        uint8_t, bool,
+                                                        InputFile *);
+template SymbolBody *SymbolTable::addUndefined<ELF32BE>(StringRef, bool,
+                                                        uint8_t, uint8_t,
+                                                        uint8_t, bool,
+                                                        InputFile *);
+template SymbolBody *SymbolTable::addUndefined<ELF64LE>(StringRef, bool,
+                                                        uint8_t, uint8_t,
+                                                        uint8_t, bool,
+                                                        InputFile *);
+template SymbolBody *SymbolTable::addUndefined<ELF64BE>(StringRef, bool,
+                                                        uint8_t, uint8_t,
+                                                        uint8_t, bool,
+                                                        InputFile *);
 
 template void SymbolTable::addSymbolAlias<ELF32LE>(StringRef, StringRef);
 template void SymbolTable::addSymbolAlias<ELF32BE>(StringRef, StringRef);
@@ -838,18 +833,18 @@ template void SymbolTable::addCombinedLT
 template void SymbolTable::addCombinedLTOObject<ELF64LE>();
 template void SymbolTable::addCombinedLTOObject<ELF64BE>();
 
-template Symbol *SymbolTable::addRegular<ELF32LE>(StringRef, uint8_t, uint8_t,
-                                                  uint64_t, uint64_t, uint8_t,
-                                                  SectionBase *, InputFile *);
-template Symbol *SymbolTable::addRegular<ELF32BE>(StringRef, uint8_t, uint8_t,
-                                                  uint64_t, uint64_t, uint8_t,
-                                                  SectionBase *, InputFile *);
-template Symbol *SymbolTable::addRegular<ELF64LE>(StringRef, uint8_t, uint8_t,
-                                                  uint64_t, uint64_t, uint8_t,
-                                                  SectionBase *, InputFile *);
-template Symbol *SymbolTable::addRegular<ELF64BE>(StringRef, uint8_t, uint8_t,
-                                                  uint64_t, uint64_t, uint8_t,
-                                                  SectionBase *, InputFile *);
+template SymbolBody *
+SymbolTable::addRegular<ELF32LE>(StringRef, uint8_t, uint8_t, uint64_t,
+                                 uint64_t, uint8_t, SectionBase *, InputFile *);
+template SymbolBody *
+SymbolTable::addRegular<ELF32BE>(StringRef, uint8_t, uint8_t, uint64_t,
+                                 uint64_t, uint8_t, SectionBase *, InputFile *);
+template SymbolBody *
+SymbolTable::addRegular<ELF64LE>(StringRef, uint8_t, uint8_t, uint64_t,
+                                 uint64_t, uint8_t, SectionBase *, InputFile *);
+template SymbolBody *
+SymbolTable::addRegular<ELF64BE>(StringRef, uint8_t, uint8_t, uint64_t,
+                                 uint64_t, uint8_t, SectionBase *, InputFile *);
 
 template DefinedRegular *SymbolTable::addAbsolute<ELF32LE>(StringRef, uint8_t,
                                                            uint8_t);
@@ -860,16 +855,16 @@ template DefinedRegular *SymbolTable::ad
 template DefinedRegular *SymbolTable::addAbsolute<ELF64BE>(StringRef, uint8_t,
                                                            uint8_t);
 
-template Symbol *
+template SymbolBody *
 SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile *,
                                      const object::Archive::Symbol);
-template Symbol *
+template SymbolBody *
 SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile *,
                                      const object::Archive::Symbol);
-template Symbol *
+template SymbolBody *
 SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile *,
                                      const object::Archive::Symbol);
-template Symbol *
+template SymbolBody *
 SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile *,
                                      const object::Archive::Symbol);
 

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Tue Oct 31 09:07:41 2017
@@ -19,8 +19,6 @@
 namespace lld {
 namespace elf {
 
-struct Symbol;
-
 // SymbolTable is a bucket of all known symbols, including defined,
 // undefined, or lazy symbols (the last one is symbols in archive
 // files whose archive members are not yet loaded).
@@ -41,22 +39,22 @@ public:
   template <class ELFT> void addSymbolWrap(StringRef Name);
   void applySymbolRenames();
 
-  ArrayRef<Symbol *> getSymbols() const { return SymVector; }
+  ArrayRef<SymbolBody *> getSymbols() const { return SymVector; }
 
   template <class ELFT>
   DefinedRegular *addAbsolute(StringRef Name,
                               uint8_t Visibility = llvm::ELF::STV_HIDDEN,
                               uint8_t Binding = llvm::ELF::STB_GLOBAL);
 
-  template <class ELFT> Symbol *addUndefined(StringRef Name);
+  template <class ELFT> SymbolBody *addUndefined(StringRef Name);
   template <class ELFT>
-  Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
-                       uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym,
-                       InputFile *File);
+  SymbolBody *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
+                           uint8_t StOther, uint8_t Type,
+                           bool CanOmitFromDynSym, InputFile *File);
   template <class ELFT>
-  Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
-                     uint64_t Value, uint64_t Size, uint8_t Binding,
-                     SectionBase *Section, InputFile *File);
+  SymbolBody *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
+                         uint64_t Value, uint64_t Size, uint8_t Binding,
+                         SectionBase *Section, InputFile *File);
 
   template <class ELFT>
   void addShared(StringRef Name, SharedFile<ELFT> *F,
@@ -64,22 +62,23 @@ public:
                  const typename ELFT::Verdef *Verdef);
 
   template <class ELFT>
-  Symbol *addLazyArchive(StringRef Name, ArchiveFile *F,
-                         const llvm::object::Archive::Symbol S);
+  SymbolBody *addLazyArchive(StringRef Name, ArchiveFile *F,
+                             const llvm::object::Archive::Symbol S);
 
   template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj);
 
-  Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
-                     uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File);
-
-  Symbol *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
-                    uint8_t Binding, uint8_t StOther, uint8_t Type,
-                    InputFile *File);
-
-  std::pair<Symbol *, bool> insert(StringRef Name);
-  std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
-                                   uint8_t Visibility, bool CanOmitFromDynSym,
-                                   InputFile *File);
+  SymbolBody *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
+                         uint8_t Type, bool CanOmitFromDynSym,
+                         BitcodeFile *File);
+
+  SymbolBody *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
+                        uint8_t Binding, uint8_t StOther, uint8_t Type,
+                        InputFile *File);
+
+  std::pair<SymbolBody *, bool> insert(StringRef Name);
+  std::pair<SymbolBody *, bool> insert(StringRef Name, uint8_t Type,
+                                       uint8_t Visibility,
+                                       bool CanOmitFromDynSym, InputFile *File);
 
   template <class ELFT> void fetchIfLazy(StringRef Name);
   template <class ELFT> void scanShlibUndefined();
@@ -94,7 +93,7 @@ public:
 private:
   std::vector<SymbolBody *> findByVersion(SymbolVersion Ver);
   std::vector<SymbolBody *> findAllByVersion(SymbolVersion Ver);
-  void defsym(Symbol *Dst, Symbol *Src);
+  void defsym(SymbolBody *Dst, SymbolBody *Src);
 
   llvm::StringMap<std::vector<SymbolBody *>> &getDemangledSyms();
   void handleAnonymousVersion();
@@ -116,7 +115,7 @@ private:
   // FIXME: Experiment with passing in a custom hashing or sorting the symbols
   // once symbol resolution is finished.
   llvm::DenseMap<llvm::CachedHashStringRef, SymIndex> Symtab;
-  std::vector<Symbol *> SymVector;
+  std::vector<SymbolBody *> SymVector;
 
   // Comdat groups define "link once" sections. If two comdat groups have the
   // same name, only one of them is linked, and the other is ignored. This set
@@ -133,8 +132,8 @@ private:
   llvm::Optional<llvm::StringMap<std::vector<SymbolBody *>>> DemangledSyms;
 
   struct SymbolRenaming {
-    Symbol *Dst;
-    Symbol *Src;
+    SymbolBody *Dst;
+    SymbolBody *Src;
     uint8_t Binding;
   };
 
@@ -142,7 +141,7 @@ private:
   std::vector<SymbolRenaming> Defsyms;
 
   // For -wrap.
-  std::vector<std::pair<Symbol *, Symbol *>> WrapSymbols;
+  std::vector<std::pair<SymbolBody *, SymbolBody *>> WrapSymbols;
 
   // For LTO.
   std::unique_ptr<BitcodeCompiler> LTO;

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Tue Oct 31 09:07:41 2017
@@ -113,7 +113,7 @@ static uint64_t getSymVA(const SymbolBod
     return 0;
   case SymbolBody::LazyArchiveKind:
   case SymbolBody::LazyObjectKind:
-    assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
+    assert(Body.IsUsedInRegularObj && "lazy symbol reached writer");
     return 0;
   }
   llvm_unreachable("invalid symbol kind");
@@ -122,7 +122,7 @@ static uint64_t getSymVA(const SymbolBod
 // Returns true if this is a weak undefined symbol.
 bool SymbolBody::isUndefWeak() const {
   // See comment on Lazy in Symbols.h for the details.
-  return !isLocal() && symbol()->isWeak() && (isUndefined() || isLazy());
+  return !isLocal() && isWeak() && (isUndefined() || isLazy());
 }
 
 InputFile *SymbolBody::getFile() const {
@@ -133,15 +133,24 @@ InputFile *SymbolBody::getFile() const {
     // SymbolBody, or having a special absolute section if needed.
     return Sec ? cast<InputSectionBase>(Sec)->File : nullptr;
   }
-  return symbol()->File;
+  return File;
 }
 
 // Overwrites all attributes with Other's so that this symbol becomes
 // an alias to Other. This is useful for handling some options such as
 // --wrap.
 void SymbolBody::copyFrom(SymbolBody *Other) {
-  memcpy(symbol()->Body.buffer, Other->symbol()->Body.buffer,
-         sizeof(Symbol::Body));
+  SymbolBody Sym = *this;
+  memcpy(this, Other, sizeof(SymbolUnion));
+
+  Binding = Sym.Binding;
+  VersionId = Sym.VersionId;
+  Visibility = Sym.Visibility;
+  IsUsedInRegularObj = Sym.IsUsedInRegularObj;
+  ExportDynamic = Sym.ExportDynamic;
+  CanInline = Sym.CanInline;
+  Traced = Sym.Traced;
+  InVersionScript = Sym.InVersionScript;
 }
 
 uint64_t SymbolBody::getVA(int64_t Addend) const {
@@ -235,9 +244,9 @@ void SymbolBody::parseSymbolVersion() {
       continue;
 
     if (IsDefault)
-      symbol()->VersionId = Ver.Id;
+      VersionId = Ver.Id;
     else
-      symbol()->VersionId = Ver.Id | VERSYM_HIDDEN;
+      VersionId = Ver.Id | VERSYM_HIDDEN;
     return;
   }
 
@@ -287,44 +296,43 @@ LazyObjFile *LazyObject::getFile() {
 
 InputFile *LazyObject::fetch() { return getFile()->fetch(); }
 
-uint8_t Symbol::computeBinding() const {
+uint8_t SymbolBody::computeBinding() const {
   if (Config->Relocatable)
     return Binding;
   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
     return STB_LOCAL;
-  if (VersionId == VER_NDX_LOCAL && body()->isInCurrentOutput())
+  if (VersionId == VER_NDX_LOCAL && isInCurrentOutput())
     return STB_LOCAL;
   if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
     return STB_GLOBAL;
   return Binding;
 }
 
-bool Symbol::includeInDynsym() const {
+bool SymbolBody::includeInDynsym() const {
   if (!Config->HasDynSymTab)
     return false;
   if (computeBinding() == STB_LOCAL)
     return false;
-  if (!body()->isInCurrentOutput())
+  if (!isInCurrentOutput())
     return true;
   return ExportDynamic;
 }
 
 // Print out a log message for --trace-symbol.
-void elf::printTraceSymbol(Symbol *Sym) {
-  SymbolBody *B = Sym->body();
+void elf::printTraceSymbol(SymbolBody *Sym) {
   std::string S;
-  if (B->isUndefined())
+  if (Sym->isUndefined())
     S = ": reference to ";
-  else if (B->isCommon())
+  else if (Sym->isCommon())
     S = ": common definition of ";
-  else if (B->isLazy())
+  else if (Sym->isLazy())
     S = ": lazy definition of ";
-  else if (B->isShared())
+  else if (Sym->isShared())
     S = ": shared definition of ";
   else
     S = ": definition of ";
 
-  message(toString(Sym->File) + S + B->getName());
+  message(toString(Sym->File) + S + Sym->getName());
 }
 
 // Returns a symbol for an error message.

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Oct 31 09:07:41 2017
@@ -34,8 +34,6 @@ template <class ELFT> class ObjFile;
 class OutputSection;
 template <class ELFT> class SharedFile;
 
-struct Symbol;
-
 // The base class for real symbol classes.
 class SymbolBody {
 public:
@@ -51,13 +49,51 @@ public:
   };
 
   SymbolBody(Kind K) : SymbolKind(K) {}
+  Kind kind() const { return static_cast<Kind>(SymbolKind); }
 
-  Symbol *symbol();
-  const Symbol *symbol() const {
-    return const_cast<SymbolBody *>(this)->symbol();
-  }
+  // Symbol binding. This is not overwritten by replaceSymbol to track
+  // changes during resolution. In particular:
+  //  - An undefined weak is still weak when it resolves to a shared library.
+  //  - An undefined weak will not fetch archive members, but we have to
+  //    remember it is weak.
+  uint8_t Binding;
 
-  Kind kind() const { return static_cast<Kind>(SymbolKind); }
+  // Version definition index.
+  uint16_t VersionId;
+
+  // Symbol visibility. This is the computed minimum visibility of all
+  // observed non-DSO symbols.
+  unsigned Visibility : 2;
+
+  // True if the symbol was used for linking and thus need to be added to the
+  // output file's symbol table. This is true for all symbols except for
+  // unreferenced DSO symbols and bitcode symbols that are unreferenced except
+  // by other bitcode objects.
+  unsigned IsUsedInRegularObj : 1;
+
+  // If this flag is true and the symbol has protected or default visibility, it
+  // will appear in .dynsym. This flag is set by interposable DSO symbols in
+  // executables, by most symbols in DSOs and executables built with
+  // --export-dynamic, and by dynamic lists.
+  unsigned ExportDynamic : 1;
+
+  // False if LTO shouldn't inline whatever this symbol points to. If a symbol
+  // is overwritten after LTO, LTO shouldn't inline the symbol because it
+  // doesn't know the final contents of the symbol.
+  unsigned CanInline : 1;
+
+  // True if this symbol is specified by --trace-symbol option.
+  unsigned Traced : 1;
+
+  // This symbol version was found in a version script.
+  unsigned InVersionScript : 1;
+
+  // The file from which this symbol was created.
+  InputFile *File = nullptr;
+
+  bool includeInDynsym() const;
+  uint8_t computeBinding() const;
+  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
 
   bool isUndefined() const { return SymbolKind == UndefinedKind; }
   bool isDefined() const { return SymbolKind <= DefinedLast; }
@@ -344,89 +380,47 @@ struct ElfSym {
   static DefinedRegular *MipsLocalGp;
 };
 
-// A real symbol object, SymbolBody, is usually stored within a Symbol. There's
-// always one Symbol for each symbol name. The resolver updates the SymbolBody
-// stored in the Body field of this object as it resolves symbols. Symbol also
-// holds computed properties of symbol names.
-struct Symbol {
-  // Symbol binding. This is on the Symbol to track changes during resolution.
-  // In particular:
-  // An undefined weak is still weak when it resolves to a shared library.
-  // An undefined weak will not fetch archive members, but we have to remember
-  // it is weak.
-  uint8_t Binding;
-
-  // Version definition index.
-  uint16_t VersionId;
-
-  // Symbol visibility. This is the computed minimum visibility of all
-  // observed non-DSO symbols.
-  unsigned Visibility : 2;
-
-  // True if the symbol was used for linking and thus need to be added to the
-  // output file's symbol table. This is true for all symbols except for
-  // unreferenced DSO symbols and bitcode symbols that are unreferenced except
-  // by other bitcode objects.
-  unsigned IsUsedInRegularObj : 1;
-
-  // If this flag is true and the symbol has protected or default visibility, it
-  // will appear in .dynsym. This flag is set by interposable DSO symbols in
-  // executables, by most symbols in DSOs and executables built with
-  // --export-dynamic, and by dynamic lists.
-  unsigned ExportDynamic : 1;
-
-  // False if LTO shouldn't inline whatever this symbol points to. If a symbol
-  // is overwritten after LTO, LTO shouldn't inline the symbol because it
-  // doesn't know the final contents of the symbol.
-  unsigned CanInline : 1;
-
-  // True if this symbol is specified by --trace-symbol option.
-  unsigned Traced : 1;
-
-  // This symbol version was found in a version script.
-  unsigned InVersionScript : 1;
-
-  // The file from which this symbol was created.
-  InputFile *File = nullptr;
-
-  bool includeInDynsym() const;
-  uint8_t computeBinding() const;
-  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
-
-  // This field is used to store the Symbol's SymbolBody. This instantiation of
-  // AlignedCharArrayUnion gives us a struct with a char array field that is
-  // large and aligned enough to store any derived class of SymbolBody.
-  llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined,
-                              SharedSymbol, LazyArchive, LazyObject>
-      Body;
-
-  SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }
-  const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
+// A buffer class that is large enough to hold any SymbolBody-derived
+// object. We allocate memory using this class and instantiate a symbol
+// using the placement new.
+union SymbolUnion {
+  alignas(DefinedRegular) char A[sizeof(DefinedRegular)];
+  alignas(DefinedCommon) char B[sizeof(DefinedCommon)];
+  alignas(Undefined) char C[sizeof(Undefined)];
+  alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
+  alignas(LazyArchive) char E[sizeof(LazyArchive)];
+  alignas(LazyObject) char F[sizeof(LazyObject)];
 };
 
-void printTraceSymbol(Symbol *Sym);
+void printTraceSymbol(SymbolBody *Sym);
 
 template <typename T, typename... ArgT>
-void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
-  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
-  static_assert(alignof(T) <= alignof(decltype(S->Body)),
-                "Body not aligned enough");
+void replaceBody(SymbolBody *S, InputFile *File, ArgT &&... Arg) {
+  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
+  static_assert(alignof(T) <= alignof(SymbolUnion),
+                "SymbolUnion not aligned enough");
   assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
          "Not a SymbolBody");
+
+  SymbolBody Sym = *S;
+
+  new (S) T(std::forward<ArgT>(Arg)...);
   S->File = File;
-  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
+
+  S->Binding = Sym.Binding;
+  S->VersionId = Sym.VersionId;
+  S->Visibility = Sym.Visibility;
+  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
+  S->ExportDynamic = Sym.ExportDynamic;
+  S->CanInline = Sym.CanInline;
+  S->Traced = Sym.Traced;
+  S->InVersionScript = Sym.InVersionScript;
 
   // Print out a log message if --trace-symbol was specified.
   // This is for debugging.
   if (S->Traced)
     printTraceSymbol(S);
 }
-
-inline Symbol *SymbolBody::symbol() {
-  assert(!isLocal());
-  return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
-                                    offsetof(Symbol, Body));
-}
 } // namespace elf
 
 std::string toString(const elf::SymbolBody &B);

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Oct 31 09:07:41 2017
@@ -66,8 +66,8 @@ uint64_t SyntheticSection::getVA() const
 // Create a .bss section for each common symbol and replace the common symbol
 // with a DefinedRegular symbol.
 template <class ELFT> void elf::createCommonSections() {
-  for (Symbol *S : Symtab->getSymbols()) {
-    auto *Sym = dyn_cast<DefinedCommon>(S->body());
+  for (SymbolBody *S : Symtab->getSymbols()) {
+    auto *Sym = dyn_cast<DefinedCommon>(S);
 
     if (!Sym)
       continue;
@@ -1533,8 +1533,7 @@ void SymbolTableBaseSection::postThunkCo
   // move all local symbols before global symbols.
   auto It = std::stable_partition(
       Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
-        return S.Symbol->isLocal() ||
-               S.Symbol->symbol()->computeBinding() == STB_LOCAL;
+        return S.Symbol->isLocal() || S.Symbol->computeBinding() == STB_LOCAL;
       });
   size_t NumLocals = It - Symbols.begin();
   getParent()->Info = NumLocals + 1;
@@ -1591,8 +1590,8 @@ template <class ELFT> void SymbolTableSe
     if (Body->isLocal()) {
       ESym->setBindingAndType(STB_LOCAL, Body->Type);
     } else {
-      ESym->setBindingAndType(Body->symbol()->computeBinding(), Body->Type);
-      ESym->setVisibility(Body->symbol()->Visibility);
+      ESym->setBindingAndType(Body->computeBinding(), Body->Type);
+      ESym->setVisibility(Body->Visibility);
     }
 
     ESym->st_name = Ent.StrTabOffset;
@@ -2284,7 +2283,7 @@ template <class ELFT> size_t VersionTabl
 template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
   auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1;
   for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
-    OutVersym->vs_index = S.Symbol->symbol()->VersionId;
+    OutVersym->vs_index = S.Symbol->VersionId;
     ++OutVersym;
   }
 }
@@ -2307,7 +2306,7 @@ template <class ELFT>
 void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) {
   auto *Ver = reinterpret_cast<const typename ELFT::Verdef *>(SS->Verdef);
   if (!Ver) {
-    SS->symbol()->VersionId = VER_NDX_GLOBAL;
+    SS->VersionId = VER_NDX_GLOBAL;
     return;
   }
 
@@ -2327,7 +2326,7 @@ void VersionNeedSection<ELFT>::addSymbol
                                           Ver->getAux()->vda_name);
     NV.Index = NextIndex++;
   }
-  SS->symbol()->VersionId = NV.Index;
+  SS->VersionId = NV.Index;
 }
 
 template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Oct 31 09:07:41 2017
@@ -425,7 +425,7 @@ static bool shouldKeepInSymtab(SectionBa
 }
 
 static bool includeInSymtab(const SymbolBody &B) {
-  if (!B.isLocal() && !B.symbol()->IsUsedInRegularObj)
+  if (!B.isLocal() && !B.IsUsedInRegularObj)
     return false;
 
   if (auto *D = dyn_cast<DefinedRegular>(&B)) {
@@ -743,10 +743,10 @@ addOptionalRegular(StringRef Name, Secti
   SymbolBody *S = Symtab->find(Name);
   if (!S || S->isInCurrentOutput())
     return nullptr;
-  Symbol *Sym = Symtab->addRegular<ELFT>(Name, StOther, STT_NOTYPE, Val,
-                                         /*Size=*/0, Binding, Sec,
-                                         /*File=*/nullptr);
-  return cast<DefinedRegular>(Sym->body());
+  SymbolBody *Sym = Symtab->addRegular<ELFT>(Name, StOther, STT_NOTYPE, Val,
+                                             /*Size=*/0, Binding, Sec,
+                                             /*File=*/nullptr);
+  return cast<DefinedRegular>(Sym);
 }
 
 // The beginning and the ending of .rel[a].plt section are marked
@@ -1188,11 +1188,11 @@ static void removeUnusedSyntheticSection
 static bool computeIsPreemptible(const SymbolBody &B) {
   assert(!B.isLocal());
   // Only symbols that appear in dynsym can be preempted.
-  if (!B.symbol()->includeInDynsym())
+  if (!B.includeInDynsym())
     return false;
 
   // Only default visibility symbols can be preempted.
-  if (B.symbol()->Visibility != STV_DEFAULT)
+  if (B.Visibility != STV_DEFAULT)
     return false;
 
   // At this point copy relocations have not been created yet, so any
@@ -1248,8 +1248,8 @@ template <class ELFT> void Writer<ELFT>:
   applySynthetic({InX::EhFrame},
                  [](SyntheticSection *SS) { SS->finalizeContents(); });
 
-  for (Symbol *S : Symtab->getSymbols())
-    S->body()->IsPreemptible |= computeIsPreemptible(*S->body());
+  for (SymbolBody *S : Symtab->getSymbols())
+    S->IsPreemptible |= computeIsPreemptible(*S);
 
   // Scan relocations. This must be done after every symbol is declared so that
   // we can correctly decide if a dynamic relocation is needed.
@@ -1263,18 +1263,16 @@ template <class ELFT> void Writer<ELFT>:
 
   // Now that we have defined all possible global symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
-  for (Symbol *S : Symtab->getSymbols()) {
-    SymbolBody *Body = S->body();
-
-    if (!includeInSymtab(*Body))
+  for (SymbolBody *Sym : Symtab->getSymbols()) {
+    if (!includeInSymtab(*Sym))
       continue;
     if (InX::SymTab)
-      InX::SymTab->addSymbol(Body);
+      InX::SymTab->addSymbol(Sym);
 
-    if (InX::DynSymTab && S->includeInDynsym()) {
-      InX::DynSymTab->addSymbol(Body);
-      if (auto *SS = dyn_cast<SharedSymbol>(Body))
-        if (cast<SharedFile<ELFT>>(S->File)->isNeeded())
+    if (InX::DynSymTab && Sym->includeInDynsym()) {
+      InX::DynSymTab->addSymbol(Sym);
+      if (auto *SS = dyn_cast<SharedSymbol>(Sym))
+        if (cast<SharedFile<ELFT>>(Sym->File)->isNeeded())
           In<ELFT>::VerNeed->addSymbol(SS);
     }
   }

Modified: lld/trunk/docs/NewLLD.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/docs/NewLLD.rst?rev=317006&r1=317005&r2=317006&view=diff
==============================================================================
--- lld/trunk/docs/NewLLD.rst (original)
+++ lld/trunk/docs/NewLLD.rst Tue Oct 31 09:07:41 2017
@@ -140,13 +140,13 @@ We will describe the key data structures
 The linker can be understood as the interactions between them.
 Once you understand their functions, the code of the linker should look obvious to you.
 
-* SymbolBody
+* Symbol
 
-  SymbolBody is a class to represent symbols.
+  This class represents a symbol.
   They are created for symbols in object files or archive files.
   The linker creates linker-defined symbols as well.
 
-  There are basically three types of SymbolBodies: Defined, Undefined, or Lazy.
+  There are basically three types of Symbols: Defined, Undefined, or Lazy.
 
   - Defined symbols are for all symbols that are considered as "resolved",
     including real defined symbols, COMDAT symbols, common symbols,
@@ -156,26 +156,17 @@ Once you understand their functions, the
   - Lazy symbols represent symbols we found in archive file headers
     which can turn into Defined if we read archieve members.
 
-* Symbol
-
-  A Symbol is a container for a SymbolBody. There's only one Symbol for each
-  unique symbol name (this uniqueness is guaranteed by the symbol table).
-  Each global symbol has only one SymbolBody at any one time, which is
-  the SymbolBody stored within a memory region of the Symbol large enough
-  to store any SymbolBody.
-
-  As the resolver reads symbols from input files, it replaces the Symbol's
-  SymbolBody with the "best" SymbolBody for its symbol name by constructing
-  the new SymbolBody in place on top of the existing SymbolBody. For example,
-  if the resolver is given a defined symbol, and the SymbolBody with its name
-  is undefined, it will construct a Defined SymbolBody over the Undefined
-  SymbolBody.
-
-  This means that each SymbolBody pointer always points to the best SymbolBody,
-  and it is possible to get from a SymbolBody to a Symbol, or vice versa,
-  by adding or subtracting a fixed offset. This memory layout helps reduce
-  the cache miss rate through high locality and a small number of required
-  pointer indirections.
+  There's only one Symbol instance for each unique symbol name. This uniqueness
+  is guaranteed by the symbol table. As the resolver reads symbols from input
+  files, it replaces an existing Symbol with the "best" Symbol for its symbol
+  name using the placement new.
+
+  The above mechanism allows you to use pointers to Symbols as a very cheap way
+  to access name resolution results. Assume for example that you have a pointer
+  to an undefined symbol before name resolution. If the symbol is resolved to a
+  defined symbol by the resolver, the pointer will "automatically" point to the
+  defined symbol, because the undefined symbol the pointer pointed to will have
+  been replaced by the defined symbol in-place.
 
 * SymbolTable
 
@@ -221,8 +212,7 @@ There are mainly three actors in this li
   InputFile is a superclass of file readers.
   We have a different subclass for each input file type,
   such as regular object file, archive file, etc.
-  They are responsible for creating and owning SymbolBodies and
-  InputSections/Chunks.
+  They are responsible for creating and owning Symbols and InputSections/Chunks.
 
 * Writer
 




More information about the llvm-commits mailing list