Index: lld/COFF/Driver.h =================================================================== --- lld/COFF/Driver.h +++ lld/COFF/Driver.h @@ -72,7 +72,7 @@ void parseDirectives(InputFile *file); // Used by ArchiveFile to enqueue members. - void enqueueArchiveMember(const Archive::Child &c, StringRef symName, + void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, StringRef parentName); MemoryBufferRef takeBuffer(std::unique_ptr mb); Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ lld/COFF/Driver.cpp @@ -268,13 +268,13 @@ } void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, - StringRef symName, + const Archive::Symbol &sym, StringRef parentName) { auto reportBufferError = [=](Error &&e, StringRef childName) { fatal("could not get the buffer for the member defining symbol " + - symName + ": " + parentName + "(" + childName + "): " + + toString(sym) + ": " + parentName + "(" + childName + "): " + toString(std::move(e))); }; @@ -285,7 +285,7 @@ reportBufferError(mbOrErr.takeError(), check(c.getFullName())); MemoryBufferRef mb = mbOrErr.get(); enqueueTask([=]() { - driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive); + driver->addArchiveBuffer(mb, toString(sym), parentName, offsetInArchive); }); return; } @@ -293,15 +293,15 @@ std::string childName = CHECK( c.getFullName(), "could not get the filename for the member defining symbol " + - symName); + toString(sym)); auto future = std::make_shared>( createFutureForFile(childName)); enqueueTask([=]() { auto mbOrErr = future->get(); if (mbOrErr.second) reportBufferError(errorCodeToError(mbOrErr.second), childName); - driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName, - parentName, /* OffsetInArchive */ 0); + driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), + toString(sym), parentName, /*OffsetInArchive=*/0); }); } Index: lld/COFF/InputFiles.h =================================================================== --- lld/COFF/InputFiles.h +++ lld/COFF/InputFiles.h @@ -96,7 +96,7 @@ // Enqueues an archive member load for the given symbol. If we've already // enqueued a load for the same archive member, this function does nothing, // which ensures that we don't load the same member more than once. - void addMember(const Archive::Symbol *sym); + void addMember(const Archive::Symbol &sym); private: std::unique_ptr file; Index: lld/COFF/InputFiles.cpp =================================================================== --- lld/COFF/InputFiles.cpp +++ lld/COFF/InputFiles.cpp @@ -85,16 +85,15 @@ } // Returns a buffer pointing to a member file containing a given symbol. -void ArchiveFile::addMember(const Archive::Symbol *sym) { - const Archive::Child &c = - CHECK(sym->getMember(), - "could not get the member for symbol " + sym->getName()); +void ArchiveFile::addMember(const Archive::Symbol &sym) { + const Archive::Child &c = CHECK( + sym.getMember(), "could not get the member for symbol " + toString(sym)); // Return an empty buffer if we have already returned the same buffer. if (!seen.insert(c.getChildOffset()).second) return; - driver->enqueueArchiveMember(c, sym->getName(), getName()); + driver->enqueueArchiveMember(c, sym, getName()); } std::vector getArchiveMembers(Archive *file) { Index: lld/COFF/SymbolTable.h =================================================================== --- lld/COFF/SymbolTable.h +++ lld/COFF/SymbolTable.h @@ -83,7 +83,7 @@ Symbol *addAbsolute(StringRef n, uint64_t va); Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias); - void addLazy(ArchiveFile *f, const Archive::Symbol sym); + void addLazy(ArchiveFile *f, const Archive::Symbol& sym); Symbol *addAbsolute(StringRef n, COFFSymbolRef s); Symbol *addRegular(InputFile *f, StringRef n, const llvm::object::coff_symbol_generic *s = nullptr, Index: lld/COFF/SymbolTable.cpp =================================================================== --- lld/COFF/SymbolTable.cpp +++ lld/COFF/SymbolTable.cpp @@ -179,7 +179,7 @@ log("Loading lazy " + l->getName() + " from " + l->file->getName() + " for automatic import"); l->pendingArchiveLoad = true; - l->file->addMember(&l->sym); + l->file->addMember(l->sym); } } @@ -363,13 +363,13 @@ if (auto *l = dyn_cast(s)) { if (!s->pendingArchiveLoad) { s->pendingArchiveLoad = true; - l->file->addMember(&l->sym); + l->file->addMember(l->sym); } } return s; } -void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) { +void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol& sym) { StringRef name = sym.getName(); Symbol *s; bool wasInserted; @@ -382,7 +382,7 @@ if (!u || u->weakAlias || s->pendingArchiveLoad) return; s->pendingArchiveLoad = true; - f->addMember(&sym); + f->addMember(sym); } void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) { Index: lld/COFF/Symbols.h =================================================================== --- lld/COFF/Symbols.h +++ lld/COFF/Symbols.h @@ -430,6 +430,7 @@ } // namespace coff std::string toString(coff::Symbol &b); +std::string toString(const coff::Archive::Symbol &b); } // namespace lld #endif Index: lld/COFF/Symbols.cpp =================================================================== --- lld/COFF/Symbols.cpp +++ lld/COFF/Symbols.cpp @@ -20,18 +20,21 @@ using namespace lld::coff; +namespace lld { + static_assert(sizeof(SymbolUnion) <= 48, "symbols should be optimized for memory usage"); // Returns a symbol name for an error message. -std::string lld::toString(coff::Symbol &b) { +static std::string demangle(StringRef symName) { if (config->demangle) - if (Optional s = lld::demangleMSVC(b.getName())) + if (Optional s = demangleMSVC(symName)) return *s; - return b.getName(); + return symName; } +std::string toString(coff::Symbol &b) { return demangle(b.getName()); } +std::string toString(const Archive::Symbol &b) { return demangle(b.getName()); } -namespace lld { namespace coff { StringRef Symbol::getName() { Index: lld/test/COFF/Inputs/mangled-symbol.s =================================================================== --- /dev/null +++ lld/test/COFF/Inputs/mangled-symbol.s @@ -0,0 +1,9 @@ + .text + + .def "?f@@YAHXZ" + .scl 2 + .type 32 + .endef + .global "?f@@YAHXZ" +"?f@@YAHXZ": + retq $0 Index: lld/test/COFF/thin-archive.s =================================================================== --- /dev/null +++ lld/test/COFF/thin-archive.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t.main.obj %s + +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t.lib.obj \ +# RUN: %S/Inputs/mangled-symbol.s +# RUN: lld-link /lib /out:%t.lib %t.lib.obj +# RUN: lld-link /lib /llvmlibthin /out:%t_thin.lib %t.lib.obj + +# RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --allow-empty %s + +# RUN: rm %t.lib.obj +# RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --check-prefix=NOOBJ %s +# RUN: not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe \ +# RUN: /demangle:no 2>&1 | FileCheck --check-prefix=NOOBJNODEMANGLE %s + +# CHECK-NOT: error: could not get the buffer for the member defining +# NOOBJ: error: could not get the buffer for the member defining symbol int __cdecl f(void): {{.*}}.lib({{.*}}.lib.obj): +# NOOBJNODEMANGLE: error: could not get the buffer for the member defining symbol ?f@@YAHXZ: {{.*}}.lib({{.*}}.lib.obj): + + .text + + .def main + .scl 2 + .type 32 + .endef + .global main +main: + call "?f@@YAHXZ" + retq $0