Index: test/MinGW/driver.test =================================================================== --- test/MinGW/driver.test +++ test/MinGW/driver.test @@ -4,6 +4,9 @@ X86-SAME: -alternatename:__image_base__=___ImageBase X86-SAME: foo.o +RUN: echo "-### foo.o -m i386pe" > %t.rsp +RUN: ld.lld @%t.rsp | FileCheck -check-prefix=X86 %s + RUN: ld.lld -### foo.o -m i386pep | FileCheck -check-prefix=X64 %s X64: -out:a.exe X64-SAME: -machine:x64 Index: tools/lld/lld.cpp =================================================================== --- tools/lld/lld.cpp +++ tools/lld/lld.cpp @@ -26,9 +26,13 @@ //===----------------------------------------------------------------------===// #include "lld/Common/Driver.h" +#include "lld/Common/Memory.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" #include @@ -59,7 +63,7 @@ .Default(Invalid); } -static bool isPETarget(const std::vector &V) { +static bool isPETarget(const SmallVector &V) { for (auto It = V.begin(); It + 1 != V.end(); ++It) { if (StringRef(*It) != "-m") continue; @@ -110,6 +114,12 @@ return parseProgname(Arg0); } +static cl::TokenizerCallback getDefaultQuotingStyle() { + if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32) + return cl::TokenizeWindowsCommandLine; + return cl::TokenizeGNUCommandLine; +} + // If this function returns true, lld calls _exit() so that it quickly // exits without invoking destructors of globally allocated objects. // @@ -125,10 +135,16 @@ std::vector Args(Argv, Argv + Argc); switch (parseFlavor(Args)) { - case Gnu: - if (isPETarget(Args)) - return !mingw::link(Args); + case Gnu: { + // Expand response files (arguments in the form of @) + // to allow deducing the PE -m argument from arguments in them. + SmallVector ExpandedArgs(Args.data(), + Args.data() + Args.size()); + cl::ExpandResponseFiles(Saver, getDefaultQuotingStyle(), ExpandedArgs); + if (isPETarget(ExpandedArgs)) + return !mingw::link(ExpandedArgs); return !elf::link(Args, canExitEarly()); + } case WinLink: return !coff::link(Args, canExitEarly()); case Darwin: