Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -152,6 +152,9 @@ def driver_mode : Joined<["--"], "driver-mode=">, Group, Flags<[CoreOption, DriverOption, HelpHidden]>, HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">; +def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group, + Flags<[CoreOption, DriverOption, HelpHidden]>, + HelpText<"Set the rsp quoting to either 'posix', or 'windows'">; def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt, HelpText<"Name for native GCC compiler">, MetaVarName<"">; Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -1813,8 +1813,9 @@ // Claim -### here. (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH); - // Claim --driver-mode, it was handled earlier. + // Claim --driver-mode, --rsp-quoting, it was handled earlier. (void)C.getArgs().hasArg(options::OPT_driver_mode); + (void)C.getArgs().hasArg(options::OPT_rsp_quoting); for (Arg *A : C.getArgs()) { // FIXME: It would be nice to be able to send the argument to the Index: test/Driver/at_file.c =================================================================== --- test/Driver/at_file.c +++ test/Driver/at_file.c @@ -14,9 +14,9 @@ // CHECK-NEXT: foo9'bar9'zed9 // CHECK-NEXT: foo10"bar10"zed10 // CHECK: bar -// CHECK: zed12 +// CHECK: zed1 // CHECK: one\two -// CHECK: c:\foo\bar.c +// CHECK: c:foobar.c foo1 foo2 Index: test/Driver/at_file.c.args =================================================================== --- test/Driver/at_file.c.args +++ test/Driver/at_file.c.args @@ -8,6 +8,7 @@ -Dfoo9=foo9\'bar9\'zed9 -Dfoo10=foo10\"bar10\"zed10 -D foo11 --Dfoo12=zed12\ +-Dfoo12=zed1\ +2 -Dfoo13='one\\two' -Dfoo14='c:\foo\bar.c' Index: test/Driver/at_file_win.c =================================================================== --- test/Driver/at_file_win.c +++ test/Driver/at_file_win.c @@ -0,0 +1,34 @@ +// RUN: %clang --rsp-quoting=windows -E %s @%s.args -o %t.log +// RUN: FileCheck --input-file=%t.log %s + +// CHECK: bar1 +// CHECK-NEXT: bar2 zed2 +// CHECK-NEXT: bar3 zed3 +// CHECK-NEXT: bar4 zed4 +// CHECK-NEXT: bar5 zed5 +// CHECK-NEXT: 'bar6 zed6' +// CHECK-NEXT: 'bar7 zed7' +// CHECK-NEXT: foo8bar8zed8 +// CHECK-NEXT: foo9\'bar9\'zed9 +// CHECK-NEXT: foo10"bar10"zed10 +// CHECK: bar +// CHECK: zed12 +// CHECK: one\two +// CHECK: c:\foo\bar.c + +foo1 +foo2 +foo3 +foo4 +foo5 +foo6 +foo7 +foo8 +foo9 +foo10 +#ifdef foo11 +bar +#endif +foo12 +foo13 +foo14 Index: test/Driver/at_file_win.c.args =================================================================== --- test/Driver/at_file_win.c.args +++ test/Driver/at_file_win.c.args @@ -0,0 +1,13 @@ +-Dfoo1=bar1 -Dfoo2="bar2 zed2" +-Dfoo3="bar3 zed3" +"-Dfoo4=bar4 zed4" +"-Dfoo5=bar5 zed5" +-Dfoo6="'bar6 zed6'" +-Dfoo7='"bar7 zed7"' +-Dfoo8=foo8"bar8"zed8 +-Dfoo9=foo9\'bar9\'zed9 +-Dfoo10=foo10\"bar10\"zed10 +-D foo11 +-Dfoo12=zed12 +-Dfoo13=one\two +-Dfoo14=c:\foo\bar.c Index: tools/driver/driver.cpp =================================================================== --- tools/driver/driver.cpp +++ tools/driver/driver.cpp @@ -345,17 +345,24 @@ }) != argv.end()) { ClangCLMode = true; } + enum { Default, POSIX, Windows } RSPQuoting = Default; + for (const char *F : argv) { + if (strcmp(F, "--rsp-quoting=posix") == 0) + RSPQuoting = POSIX; + else if (strcmp(F, "--rsp-quoting=windows") == 0) + RSPQuoting = Windows; + } // Determines whether we want nullptr markers in argv to indicate response // files end-of-lines. We only use this for the /LINK driver argument with // clang-cl.exe on Windows. - bool MarkEOLs = false; + bool MarkEOLs = ClangCLMode; - llvm::cl::TokenizerCallback Tokenizer = &llvm::cl::TokenizeGNUCommandLine; - if (ClangCLMode) { + llvm::cl::TokenizerCallback Tokenizer; + if (RSPQuoting == Windows || (RSPQuoting == Default && ClangCLMode)) Tokenizer = &llvm::cl::TokenizeWindowsCommandLine; - MarkEOLs = true; - } + else + Tokenizer = &llvm::cl::TokenizeGNUCommandLine; if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) MarkEOLs = false;