Remove `Type` parameter from SymbolTable::insert(). NFC.

`Type` parameter was used only to check for TLS attribute mismatch,
but we can do that when we actually replace symbols, so we don't need
to type as an argument. This change should simplify the interface of
the symbol table a bit.

git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@344394 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index d189862..d1ca2a6 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -169,7 +169,7 @@
   // Define a symbol.
   Symbol *Sym;
   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
+  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
                                               /*CanOmitFromDynSym*/ false,
                                               /*File*/ nullptr);
   ExprValue Value = Cmd->Expression();
@@ -202,7 +202,7 @@
   // We can't calculate final value right now.
   Symbol *Sym;
   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
+  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
                                               /*CanOmitFromDynSym*/ false,
                                               /*File*/ nullptr);
   replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index 38d0edc..f99b2a3 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -197,6 +197,7 @@
     return {SymVector[SymIndex], false};
 
   auto *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+  Sym->SymbolKind = Symbol::PlaceholderKind;
   Sym->Visibility = STV_DEFAULT;
   Sym->IsUsedInRegularObj = false;
   Sym->ExportDynamic = false;
@@ -209,7 +210,7 @@
 
 // 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,
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
                                               uint8_t Visibility,
                                               bool CanOmitFromDynSym,
                                               InputFile *File) {
@@ -226,11 +227,6 @@
   if (!File || File->kind() == InputFile::ObjKind)
     S->IsUsedInRegularObj = true;
 
-  bool HasTlsAttr = !WasInserted && (!S->isLazy() || S->isTls());
-  if (HasTlsAttr && (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};
 }
 
@@ -243,8 +239,7 @@
   Symbol *S;
   bool WasInserted;
   uint8_t Visibility = getVisibility(StOther);
-  std::tie(S, WasInserted) =
-      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
+  std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
 
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
@@ -392,7 +387,7 @@
                                InputFile &File) {
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
+  std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, &File);
 
   int Cmp = compareDefined(S, WasInserted, Binding, N);
@@ -469,7 +464,7 @@
                                 SectionBase *Section, InputFile *File) {
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
+  std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, File);
   int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
                                     Value, Name);
@@ -491,7 +486,7 @@
   // unchanged.
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
+  std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
                                     /*CanOmitFromDynSym*/ true, &File);
   // Make sure we preempt DSO symbols with default visibility.
   if (Sym.getVisibility() == STV_DEFAULT)
@@ -520,7 +515,7 @@
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) =
-      insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F);
+      insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
   int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
                                     /*IsAbs*/ false, /*Value*/ 0, Name);
   if (Cmp > 0)
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index fbf2fd8..e91e5cc 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -67,9 +67,8 @@
                     uint8_t Binding, uint8_t StOther, uint8_t Type,
                     InputFile &File);
 
-  std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
-                                   uint8_t Visibility, bool CanOmitFromDynSym,
-                                   InputFile *File);
+  std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
+                                   bool CanOmitFromDynSym, InputFile *File);
 
   template <class ELFT> void fetchLazy(Symbol *Sym);
 
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index 7a35377..0ed0ef6 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -110,6 +110,8 @@
   case Symbol::LazyObjectKind:
     assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
     return 0;
+  case Symbol::PlaceholderKind:
+    llvm_unreachable("placeholder symbol reached writer");
   }
   llvm_unreachable("invalid symbol kind");
 }
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index 7bae773..f380861 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -22,6 +22,14 @@
 
 namespace lld {
 namespace elf {
+class Symbol;
+class InputFile;
+} // namespace elf
+
+std::string toString(const elf::Symbol &);
+std::string toString(const elf::InputFile *);
+
+namespace elf {
 
 class ArchiveFile;
 class BitcodeFile;
@@ -50,6 +58,7 @@
 class Symbol {
 public:
   enum Kind {
+    PlaceholderKind,
     DefinedKind,
     SharedKind,
     UndefinedKind,
@@ -89,7 +98,7 @@
   uint8_t Type;    // symbol type
   uint8_t StOther; // st_other field value
 
-  const uint8_t SymbolKind;
+  uint8_t SymbolKind;
 
   // Symbol visibility. This is the computed minimum visibility of all
   // observed non-DSO symbols.
@@ -359,6 +368,8 @@
 
 template <typename T, typename... ArgT>
 void replaceSymbol(Symbol *S, ArgT &&... Arg) {
+  using llvm::ELF::STT_TLS;
+
   static_assert(std::is_trivially_destructible<T>(),
                 "Symbol types must be trivially destructible");
   static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
@@ -379,6 +390,18 @@
   S->Traced = Sym.Traced;
   S->ScriptDefined = Sym.ScriptDefined;
 
+  // Symbols representing thread-local variables must be referenced by
+  // TLS-aware relocations, and non-TLS symbols must be reference by
+  // non-TLS relocations, so there's a clear distinction between TLS
+  // and non-TLS symbols. It is an error if the same symbol is defined
+  // as a TLS symbol in one file and as a non-TLS symbol in other file.
+  bool TlsMismatch = (Sym.Type == STT_TLS && S->Type != STT_TLS) ||
+                     (Sym.Type != STT_TLS && S->Type == STT_TLS);
+
+  if (Sym.SymbolKind != Symbol::PlaceholderKind && TlsMismatch && !Sym.isLazy())
+    error("TLS attribute mismatch: " + toString(Sym) + "\n>>> defined in " +
+          toString(Sym.File) + "\n>>> defined in " + toString(S->File));
+
   // Print out a log message if --trace-symbol was specified.
   // This is for debugging.
   if (S->Traced)
@@ -387,8 +410,6 @@
 
 void warnUnorderableSymbol(const Symbol *Sym);
 } // namespace elf
-
-std::string toString(const elf::Symbol &B);
 } // namespace lld
 
 #endif