Index: ELF/DriverUtils.cpp =================================================================== --- ELF/DriverUtils.cpp +++ ELF/DriverUtils.cpp @@ -17,6 +17,7 @@ #include "Error.h" #include "lld/Config/Version.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" @@ -49,19 +50,38 @@ ELFOptTable::ELFOptTable() : OptTable(OptInfo) {} +static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { + if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) { + StringRef S = Arg->getValue(); + if (S != "windows" && S != "posix") + error("invalid response file quoting: " + S); + if (S == "windows") + return cl::TokenizeWindowsCommandLine; + return cl::TokenizeGNUCommandLine; + } + if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32) + return cl::TokenizeWindowsCommandLine; + return cl::TokenizeGNUCommandLine; +} + // Parses a given list of options. opt::InputArgList ELFOptTable::parse(ArrayRef Argv) { // Make InputArgList from string vectors. unsigned MissingIndex; unsigned MissingCount; + SmallVector Vec(Argv.data(), Argv.data() + Argv.size()); + + // We need to get the quoting style for response files before parsing all + // options so we parse here before and ignore all the options but + // --rsp-quoting. + opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); // Expand response files. '@' is replaced by the file's contents. - SmallVector Vec(Argv.data(), Argv.data() + Argv.size()); StringSaver Saver(Alloc); - cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec); + cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec); // Parse options and then do error checking. - opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); + Args = this->ParseArgs(Vec, MissingIndex, MissingCount); if (MissingCount) error(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) + "\", expected " + Twine(MissingCount) + Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -156,6 +156,9 @@ def unresolved_symbols: J<"unresolved-symbols=">, HelpText<"Determine how to handle unresolved symbols">; +def rsp_quoting: J<"rsp-quoting=">, + HelpText<"Quoting style for response files. Values supported: windows|posix">; + def verbose: F<"verbose">, HelpText<"Verbose mode">; def version: F<"version">, HelpText<"Display the version number">; Index: test/ELF/basic.s =================================================================== --- test/ELF/basic.s +++ test/ELF/basic.s @@ -184,12 +184,23 @@ # CHECK-NEXT: } # CHECK-NEXT: ] -# Test for the response file +# Test for the response file (POSIX quoting style) # RUN: echo " -o %t2" > %t.responsefile -# RUN: ld.lld %t @%t.responsefile +# RUN: ld.lld %t --rsp-quoting=posix @%t.responsefile # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ # RUN: | FileCheck %s +# Test for the response file (Windows quoting style) +# RUN: echo " c:\blah\foo" > %t.responsefile +# RUN: not ld.lld --rsp-quoting=windows %t @%t.responsefile 2>&1 | FileCheck \ +# RUN: %s --check-prefix=WINRSP +# WINRSP: cannot open c:\blah\foo + +# Test for the response file (invalid quoting style) +# RUN: not ld.lld --rsp-quoting=patatino %t 2>&1 | FileCheck %s \ +# RUN: --check-prefix=INVRSP +# INVRSP: invalid response file quoting: patatino + # RUN: not ld.lld %t.foo -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=MISSING %s # MISSING: cannot open {{.*}}.foo: {{[Nn]}}o such file or directory