Split Defined and DefinedElf.

This is similar to what was done for Undefined and opens the way for
having a symbol defined in bitcode.

llvm-svn: 256354
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 51fac66..f28c87c 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -130,7 +130,7 @@
 template <class ELFT>
 static typename llvm::object::ELFFile<ELFT>::uintX_t
 getSymSize(SymbolBody &Body) {
-  if (auto *SS = dyn_cast<Defined<ELFT>>(&Body))
+  if (auto *SS = dyn_cast<DefinedElf<ELFT>>(&Body))
     return SS->Sym.st_size;
   return 0;
 }
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 818611e..b48538c 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -787,7 +787,7 @@
   switch (S.kind()) {
   case SymbolBody::DefinedSyntheticKind: {
     auto &D = cast<DefinedSynthetic<ELFT>>(S);
-    return D.Section.getVA() + D.Sym.st_value;
+    return D.Section.getVA() + D.Value;
   }
   case SymbolBody::DefinedAbsoluteKind:
     return cast<DefinedAbsolute<ELFT>>(S).Sym.st_value;
@@ -1320,7 +1320,7 @@
 template <class ELFT>
 static const typename llvm::object::ELFFile<ELFT>::Elf_Sym *
 getElfSym(SymbolBody &Body) {
-  if (auto *EBody = dyn_cast<Defined<ELFT>>(&Body))
+  if (auto *EBody = dyn_cast<DefinedElf<ELFT>>(&Body))
     return &EBody->Sym;
   if (auto *EBody = dyn_cast<UndefinedElf<ELFT>>(&Body))
     return &EBody->Sym;
@@ -1392,6 +1392,8 @@
     return STB_LOCAL;
   if (const Elf_Sym *ESym = getElfSym<ELFT>(*Body))
     return ESym->getBinding();
+  if (isa<DefinedSynthetic<ELFT>>(Body))
+    return STB_LOCAL;
   return Body->isWeak() ? STB_WEAK : STB_GLOBAL;
 }
 
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index d3fd3e3..00e21d0 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -102,11 +102,7 @@
 void SymbolTable<ELFT>::addSynthetic(StringRef Name,
                                      OutputSectionBase<ELFT> &Section,
                                      typename ELFFile<ELFT>::uintX_t Value) {
-  typedef typename DefinedSynthetic<ELFT>::Elf_Sym Elf_Sym;
-  auto *ESym = new (Alloc) Elf_Sym;
-  memset(ESym, 0, sizeof(Elf_Sym));
-  ESym->st_value = Value;
-  auto *Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, *ESym, Section);
+  auto *Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, Value, Section);
   resolve(Sym);
 }
 
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 6f8d575..5c65952 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -73,6 +73,10 @@
   return 0;
 }
 
+Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
+                 bool IsTls)
+    : SymbolBody(K, Name, IsWeak, Visibility, IsTls) {}
+
 Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,
                      uint8_t Visibility, bool IsTls)
     : SymbolBody(K, N, IsWeak, Visibility, IsTls), CanKeepUndefined(false) {}
@@ -91,6 +95,12 @@
                 Sym.getType() == llvm::ELF::STT_TLS),
       Sym(Sym) {}
 
+template <typename ELFT>
+DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
+                                         OutputSectionBase<ELFT> &Section)
+    : Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT, false),
+      Value(Value), Section(Section) {}
+
 std::unique_ptr<InputFile> Lazy::getMember() {
   MemoryBufferRef MBRef = File->getMember(&Sym);
 
@@ -124,3 +134,8 @@
 template class lld::elf2::UndefinedElf<ELF32BE>;
 template class lld::elf2::UndefinedElf<ELF64LE>;
 template class lld::elf2::UndefinedElf<ELF64BE>;
+
+template class lld::elf2::DefinedSynthetic<ELF32LE>;
+template class lld::elf2::DefinedSynthetic<ELF32BE>;
+template class lld::elf2::DefinedSynthetic<ELF64LE>;
+template class lld::elf2::DefinedSynthetic<ELF64BE>;
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 8899192..2ce4fe8 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -59,9 +59,10 @@
     DefinedRegularKind = DefinedFirst,
     DefinedAbsoluteKind,
     DefinedCommonKind,
-    DefinedSyntheticKind,
     SharedKind,
-    DefinedLast = SharedKind,
+    DefinedElfLast = SharedKind,
+    DefinedSyntheticKind,
+    DefinedLast = DefinedSyntheticKind,
     UndefinedElfKind,
     UndefinedKind,
     LazyKind
@@ -131,21 +132,30 @@
 };
 
 // The base class for any defined symbols, including absolute symbols, etc.
-template <class ELFT> class Defined : public SymbolBody {
+class Defined : public SymbolBody {
+public:
+  Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, bool IsTls);
+  static bool classof(const SymbolBody *S) { return S->isDefined(); }
+};
+
+// Any defined symbol from an ELF file.
+template <class ELFT> class DefinedElf : public Defined {
 protected:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
 
 public:
-  Defined(Kind K, StringRef N, const Elf_Sym &Sym)
-      : SymbolBody(K, N, Sym.getBinding() == llvm::ELF::STB_WEAK,
-                   Sym.getVisibility(), Sym.getType() == llvm::ELF::STT_TLS),
+  DefinedElf(Kind K, StringRef N, const Elf_Sym &Sym)
+      : Defined(K, N, Sym.getBinding() == llvm::ELF::STB_WEAK,
+                Sym.getVisibility(), Sym.getType() == llvm::ELF::STT_TLS),
         Sym(Sym) {}
 
   const Elf_Sym &Sym;
-  static bool classof(const SymbolBody *S) { return S->isDefined(); }
+  static bool classof(const SymbolBody *S) {
+    return S->kind() <= DefinedElfLast;
+  }
 };
 
-template <class ELFT> class DefinedAbsolute : public Defined<ELFT> {
+template <class ELFT> class DefinedAbsolute : public DefinedElf<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
 
 public:
@@ -167,7 +177,7 @@
   static Elf_Sym RelaIpltEnd;
 
   DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
-      : Defined<ELFT>(SymbolBody::DefinedAbsoluteKind, N, Sym) {}
+      : DefinedElf<ELFT>(SymbolBody::DefinedAbsoluteKind, N, Sym) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == SymbolBody::DefinedAbsoluteKind;
@@ -189,13 +199,13 @@
 template <class ELFT>
 typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::RelaIpltEnd;
 
-template <class ELFT> class DefinedCommon : public Defined<ELFT> {
+template <class ELFT> class DefinedCommon : public DefinedElf<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
 
 public:
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   DefinedCommon(StringRef N, const Elf_Sym &Sym)
-      : Defined<ELFT>(SymbolBody::DefinedCommonKind, N, Sym) {
+      : DefinedElf<ELFT>(SymbolBody::DefinedCommonKind, N, Sym) {
     MaxAlignment = Sym.st_value;
   }
 
@@ -212,13 +222,13 @@
 };
 
 // Regular defined symbols read from object file symbol tables.
-template <class ELFT> class DefinedRegular : public Defined<ELFT> {
+template <class ELFT> class DefinedRegular : public DefinedElf<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
 
 public:
   DefinedRegular(StringRef N, const Elf_Sym &Sym,
                  InputSectionBase<ELFT> &Section)
-      : Defined<ELFT>(SymbolBody::DefinedRegularKind, N, Sym),
+      : DefinedElf<ELFT>(SymbolBody::DefinedRegularKind, N, Sym),
         Section(Section) {}
 
   static bool classof(const SymbolBody *S) {
@@ -232,18 +242,18 @@
 // The difference from the regular symbol is that DefinedSynthetic symbols
 // don't belong to any input files or sections. Thus, its constructor
 // takes an output section to calculate output VA, etc.
-template <class ELFT> class DefinedSynthetic : public Defined<ELFT> {
+template <class ELFT> class DefinedSynthetic : public Defined {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
-  DefinedSynthetic(StringRef N, const Elf_Sym &Sym,
-                   OutputSectionBase<ELFT> &Section)
-      : Defined<ELFT>(SymbolBody::DefinedSyntheticKind, N, Sym),
-        Section(Section) {}
+  typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
+  DefinedSynthetic(StringRef N, uintX_t Value,
+                   OutputSectionBase<ELFT> &Section);
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == SymbolBody::DefinedSyntheticKind;
   }
 
+  uintX_t Value;
   const OutputSectionBase<ELFT> &Section;
 };
 
@@ -276,7 +286,7 @@
   }
 };
 
-template <class ELFT> class SharedSymbol : public Defined<ELFT> {
+template <class ELFT> class SharedSymbol : public DefinedElf<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
@@ -286,7 +296,7 @@
   }
 
   SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)
-      : Defined<ELFT>(SymbolBody::SharedKind, Name, Sym), File(F) {}
+      : DefinedElf<ELFT>(SymbolBody::SharedKind, Name, Sym), File(F) {}
 
   SharedFile<ELFT> *File;
 
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 0456b44..ea15ef9 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -71,7 +71,7 @@
 }
 
 template <class ELFT> bool isGnuIFunc(const SymbolBody &S) {
-  if (auto *SS = dyn_cast<Defined<ELFT>>(&S))
+  if (auto *SS = dyn_cast<DefinedElf<ELFT>>(&S))
     return SS->Sym.getType() == STT_GNU_IFUNC;
   return false;
 }