diff options
Diffstat (limited to 'lld/COFF/SymbolTable.cpp')
-rw-r--r-- | lld/COFF/SymbolTable.cpp | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 5d999f18c49..538173d7554 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -24,36 +24,6 @@ using namespace llvm; namespace lld { namespace coff { -enum SymbolPreference { - SP_EXISTING = -1, - SP_CONFLICT = 0, - SP_NEW = 1, -}; - -/// Checks if an existing symbol S should be kept or replaced by a new symbol. -/// Returns SP_EXISTING when S should be kept, SP_NEW when the new symbol -/// should be kept, and SP_CONFLICT if no valid resolution exists. -static SymbolPreference compareDefined(Symbol *S, bool WasInserted, - bool NewIsCOMDAT) { - // If the symbol wasn't previously known, the new symbol wins by default. - if (WasInserted || !isa<Defined>(S)) - return SP_NEW; - - // If the existing symbol is a DefinedRegular, both it and the new symbol - // must be comdats. In that case, we have no reason to prefer one symbol - // over the other, and we keep the existing one. If one of the symbols - // is not a comdat, we report a conflict. - if (auto *R = dyn_cast<DefinedRegular>(S)) { - if (NewIsCOMDAT && R->isCOMDAT()) - return SP_EXISTING; - else - return SP_CONFLICT; - } - - // Existing symbol is not a DefinedRegular; new symbol wins. - return SP_NEW; -} - SymbolTable *Symtab; void SymbolTable::addFile(InputFile *File) { @@ -239,7 +209,7 @@ Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) { return S; } -Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, +Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, const coff_symbol_generic *Sym, SectionChunk *C) { Symbol *S; @@ -247,22 +217,32 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, std::tie(S, WasInserted) = insert(N); if (!isa<BitcodeFile>(F)) S->IsUsedInRegularObj = true; - SymbolPreference SP = compareDefined(S, WasInserted, IsCOMDAT); - if (SP == SP_CONFLICT) { + if (WasInserted || !isa<DefinedRegular>(S)) + replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false, + /*IsExternal*/ true, Sym, C); + else reportDuplicate(S, F); - } else if (SP == SP_NEW) { - replaceSymbol<DefinedRegular>(S, F, N, IsCOMDAT, /*IsExternal*/ true, Sym, - C); - } else if (SP == SP_EXISTING && IsCOMDAT && C) { - C->markDiscarded(); - // Discard associative chunks that we've parsed so far. No need to recurse - // because an associative section cannot have children. - for (SectionChunk *Child : C->children()) - Child->markDiscarded(); - } return S; } +std::pair<Symbol *, bool> +SymbolTable::addComdat(InputFile *F, StringRef N, + const coff_symbol_generic *Sym) { + Symbol *S; + bool WasInserted; + std::tie(S, WasInserted) = insert(N); + if (!isa<BitcodeFile>(F)) + S->IsUsedInRegularObj = true; + if (WasInserted || !isa<DefinedRegular>(S)) { + replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true, + /*IsExternal*/ true, Sym, nullptr); + return {S, true}; + } + if (!cast<DefinedRegular>(S)->isCOMDAT()) + reportDuplicate(S, F); + return {S, false}; +} + Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, const coff_symbol_generic *Sym, CommonChunk *C) { Symbol *S; |