Index: lld/COFF/Driver.h =================================================================== --- lld/COFF/Driver.h +++ lld/COFF/Driver.h @@ -169,10 +169,8 @@ // incompatible objects. void checkFailIfMismatch(StringRef Arg); -// Convert Windows resource files (.res files) to a .obj file -// using cvtres.exe. -std::unique_ptr -convertResToCOFF(const std::vector &MBs); +// Convert Windows resource files (.res files) to a .obj file. +MemoryBufferRef convertResToCOFF(const std::vector &MBs); void runMSVCLinker(std::string Rsp, ArrayRef Objects); Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ lld/COFF/Driver.cpp @@ -113,16 +113,15 @@ void LinkerDriver::addBuffer(std::unique_ptr MB, bool WholeArchive) { MemoryBufferRef MBRef = takeBuffer(std::move(MB)); + FilePaths.push_back(MBRef.getBufferIdentifier()); // File type is detected by contents, not by file extension. - file_magic Magic = identify_magic(MBRef.getBuffer()); - if (Magic == file_magic::windows_resource) { + switch (identify_magic(MBRef.getBuffer())) { + case file_magic::windows_resource: Resources.push_back(MBRef); - return; - } + break; - FilePaths.push_back(MBRef.getBufferIdentifier()); - if (Magic == file_magic::archive) { + case file_magic::archive: if (WholeArchive) { std::unique_ptr File = check(Archive::create(MBRef), @@ -133,19 +132,21 @@ return; } Symtab->addFile(make(MBRef)); - return; - } + break; - if (Magic == file_magic::bitcode) { + case file_magic::bitcode: Symtab->addFile(make(MBRef)); - return; - } + break; - if (Magic == file_magic::coff_cl_gl_object) + case file_magic::coff_cl_gl_object: error(MBRef.getBufferIdentifier() + ": is not a native COFF file. " "Recompile without /GL"); - else + break; + + default: Symtab->addFile(make(MBRef)); + break; + } } void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) { @@ -1078,7 +1079,7 @@ // WindowsResource to convert resource files to a regular COFF file, // then link the resulting file normally. if (!Resources.empty()) - addBuffer(convertResToCOFF(Resources), false); + Symtab->addFile(make(convertResToCOFF(Resources))); if (Tar) Tar->append("response.txt", Index: lld/COFF/DriverUtils.cpp =================================================================== --- lld/COFF/DriverUtils.cpp +++ lld/COFF/DriverUtils.cpp @@ -639,10 +639,8 @@ Config->MustMatch[K] = V; } -// Convert Windows resource files (.res files) to a .obj file -// using cvtres.exe. -std::unique_ptr -convertResToCOFF(const std::vector &MBs) { +// Convert Windows resource files (.res files) to a .obj file. +MemoryBufferRef convertResToCOFF(const std::vector &MBs) { object::WindowsResourceParser Parser; for (MemoryBufferRef MB : MBs) { @@ -658,7 +656,10 @@ llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser); if (!E) fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF"); - return std::move(E.get()); + + MemoryBufferRef MBRef = **E; + make>(std::move(*E)); // take ownership + return MBRef; } // Run MSVC link.exe for given in-memory object files. Index: lld/test/COFF/linkrepro-res.test =================================================================== --- /dev/null +++ lld/test/COFF/linkrepro-res.test @@ -0,0 +1,12 @@ +# REQUIRES: x86, shell + +# RUN: rm -rf %t.dir +# RUN: mkdir -p %t.dir/build +# RUN: cd %t.dir/build +# RUN: lld-link %p/Inputs/resource.res /subsystem:console /machine:x64 \ +# RUN: /entry:__ImageBase /linkrepro:. /out:%t.exe +# RUN: tar xf repro.tar +# RUN: diff %p/Inputs/resource.res repro/%:p/Inputs/resource.res +# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt + +# RSP: resource.res