summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Driver/Options.td3
-rw-r--r--clang/lib/Driver/Driver.cpp3
-rw-r--r--clang/test/Driver/at_file_win.c34
-rw-r--r--clang/test/Driver/at_file_win.c.args13
-rw-r--r--clang/tools/driver/driver.cpp17
5 files changed, 64 insertions, 6 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9bc6bbc6979..d2e66572884 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -152,6 +152,9 @@ class InternalDriverOpt : Group<internal_driver_Group>,
def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>,
Flags<[CoreOption, DriverOption, HelpHidden]>,
HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">;
+def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group<internal_driver_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<"<gcc-path>">;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index b855b9c5921..7ff403baff0 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1813,8 +1813,9 @@ void Driver::BuildJobs(Compilation &C) const {
// 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
diff --git a/clang/test/Driver/at_file_win.c b/clang/test/Driver/at_file_win.c
new file mode 100644
index 00000000000..9a8ede548a2
--- /dev/null
+++ b/clang/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
diff --git a/clang/test/Driver/at_file_win.c.args b/clang/test/Driver/at_file_win.c.args
new file mode 100644
index 00000000000..df109e4d5fd
--- /dev/null
+++ b/clang/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
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index b7097e3faf1..b74de081991 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -345,17 +345,24 @@ int main(int argc_, const char **argv_) {
}) != 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;
OpenPOWER on IntegriCloud