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: