COFF: Separate DefinedCOMDAT from DefinedRegular symbol type. NFC.

Before this change, you got to cast a symbol to DefinedRegular and then
call isCOMDAT() to determine if a given symbol is a COMDAT symbol.
Now you can just use isa<DefinedCOMDAT>().

As to the class definition of DefinedCOMDAT, I could remove duplicate
code from DefinedRegular and DefinedCOMDAT by introducing another base
class for them, but I chose to not do that to keep the class hierarchy
shallow. This amount of code duplication doesn't worth to define a new
class.

llvm-svn: 240319
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index d9cdd2f..f2734ea 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -211,8 +211,11 @@
       }
     }
   }
-  if (Chunk *C = SparseChunks[Sym.getSectionNumber()])
+  if (Chunk *C = SparseChunks[Sym.getSectionNumber()]) {
+    if (C->isCOMDAT())
+      return new (Alloc) DefinedCOMDAT(COFFObj.get(), Sym, C);
     return new (Alloc) DefinedRegular(COFFObj.get(), Sym, C);
+  }
   return nullptr;
 }
 
diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp
index af2cf0d..02cf732 100644
--- a/lld/COFF/Symbols.cpp
+++ b/lld/COFF/Symbols.cpp
@@ -26,12 +26,17 @@
 int DefinedRegular::compare(SymbolBody *Other) {
   if (Other->kind() < kind())
     return -Other->compare(this);
-  auto *R = dyn_cast<DefinedRegular>(Other);
-  if (!R)
-    return 1;
-  if (isCOMDAT() && R->isCOMDAT())
-    return 1;
-  return 0;
+  if (isa<DefinedRegular>(Other))
+    return 0;
+  return 1;
+}
+
+int DefinedCOMDAT::compare(SymbolBody *Other) {
+  if (Other->kind() < kind())
+    return -Other->compare(this);
+  if (isa<DefinedRegular>(Other))
+    return 0;
+  return 1;
 }
 
 int DefinedCommon::compare(SymbolBody *Other) {
@@ -39,9 +44,9 @@
     return -Other->compare(this);
   if (auto *D = dyn_cast<DefinedCommon>(Other))
     return getSize() > D->getSize() ? 1 : -1;
-  if (isa<DefinedRegular>(Other))
-    return -1;
-  return 1;
+  if (isa<Lazy>(Other) || isa<Undefined>(Other))
+    return 1;
+  return -1;
 }
 
 int DefinedBitcode::compare(SymbolBody *Other) {
@@ -62,12 +67,9 @@
   // replicate the rest of the symbol resolution logic here; symbol
   // resolution will be done accurately after lowering bitcode symbols
   // to regular symbols in addCombinedLTOObject().
-  if (auto *R = dyn_cast<DefinedRegular>(Other)) {
-    if (!R->isCOMDAT() && !Replaceable)
-      return 0;
+  if (isa<DefinedRegular>(Other) && Replaceable)
     return -1;
-  }
-  if (isa<DefinedCommon>(Other))
+  if (isa<DefinedCommon>(Other) || isa<DefinedCOMDAT>(Other))
     return -1;
   return 0;
 }
@@ -115,6 +117,12 @@
   return Name;
 }
 
+StringRef DefinedCOMDAT::getName() {
+  if (Name.empty())
+    COFFFile->getSymbolName(Sym, Name);
+  return Name;
+}
+
 StringRef DefinedCommon::getName() {
   if (Name.empty())
     COFFFile->getSymbolName(Sym, Name);
diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h
index 62fbd54..344c089d 100644
--- a/lld/COFF/Symbols.h
+++ b/lld/COFF/Symbols.h
@@ -50,6 +50,7 @@
     DefinedImportDataKind,
     DefinedImportThunkKind,
     DefinedCommonKind,
+    DefinedCOMDATKind,
     DefinedRegularKind,
     DefinedLast,
     LazyKind,
@@ -128,7 +129,29 @@
   bool isExternal() override { return Sym.isExternal(); }
   void markLive() override { Data->markLive(); }
   uint64_t getFileOff() override { return Data->getFileOff() + Sym.getValue(); }
-  bool isCOMDAT() const { return Data->isCOMDAT(); }
+  int compare(SymbolBody *Other) override;
+
+private:
+  StringRef Name;
+  COFFObjectFile *COFFFile;
+  COFFSymbolRef Sym;
+  Chunk *Data;
+};
+
+class DefinedCOMDAT : public Defined {
+public:
+  DefinedCOMDAT(COFFObjectFile *F, COFFSymbolRef S, Chunk *C)
+      : Defined(DefinedCOMDATKind), COFFFile(F), Sym(S), Data(C) {}
+
+  static bool classof(const SymbolBody *S) {
+    return S->kind() == DefinedCOMDATKind;
+  }
+
+  StringRef getName() override;
+  uint64_t getRVA() override { return Data->getRVA() + Sym.getValue(); }
+  bool isExternal() override { return Sym.isExternal(); }
+  void markLive() override { Data->markLive(); }
+  uint64_t getFileOff() override { return Data->getFileOff() + Sym.getValue(); }
   int compare(SymbolBody *Other) override;
 
 private: