Skip to content

Commit 67aaabd

Browse files
Jason Mittertreinergmittert
authored andcommitted
Fix Response Files on Windows
This prevents response files on Windows from being overridden after they are read.
1 parent 003850f commit 67aaabd

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

test/Driver/response-file-merge-modules.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// RUN: %swiftc_driver -driver-print-jobs -module-name merge -emit-module %S/Inputs/main.swift %S/Inputs/lib.swift @%t.resp 2>&1 > %t.jobs.txt
33
// RUN: %FileCheck %s < %t.jobs.txt -check-prefix=MERGE
44

5-
// MERGE: bin/swift{{c?}}
6-
// MERGE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp # -frontend -emit-module -primary-file {{[^ ]+}}/Inputs/main.swift {{[^ ]+}}/Inputs/lib.swift
7-
// MERGE: -emit-module-doc-path [[PARTIAL_MODULE_A:[^ ]+]].swiftdoc
8-
// MERGE: bin/swift{{c?}}
9-
// MERGE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp # -frontend -emit-module {{[^ ]+}}/Inputs/main.swift -primary-file {{[^ ]+}}/Inputs/lib.swift
10-
// MERGE: -emit-module-doc-path [[PARTIAL_MODULE_B:[^ ]+]].swiftdoc
11-
// MERGE: bin/swift{{c?}}
12-
// MERGE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp # -frontend -merge-modules -emit-module [[PARTIAL_MODULE_A]].swiftmodule [[PARTIAL_MODULE_B]].swiftmodule
5+
// MERGE: bin{{/|\\\\}}swift{{c?}}
6+
// MERGE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp{{"?}} # -frontend -emit-module -primary-file {{[^ ]+}}/Inputs/main.swift{{"?}} {{[^ ]+}}/Inputs/lib.swift
7+
// MERGE: -emit-module-doc-path {{"?}}[[PARTIAL_MODULE_A:[^ ]+]].swiftdoc
8+
// MERGE: bin{{/|\\\\}}swift{{c?}}
9+
// MERGE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp{{"?}} # -frontend -emit-module {{[^ ]+}}/Inputs/main.swift{{"?}} -primary-file {{[^ ]+}}/Inputs/lib.swift
10+
// MERGE: -emit-module-doc-path {{"?}}[[PARTIAL_MODULE_B:[^ ]+]].swiftdoc
11+
// MERGE: bin{{/|\\\\}}swift{{c?}}
12+
// MERGE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp{{"?}} # -frontend -merge-modules -emit-module {{"?}}[[PARTIAL_MODULE_A]].swiftmodule{{"?}} {{"?}}[[PARTIAL_MODULE_B]].swiftmodule

test/Driver/response-file.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@
2828
// RUN: %target-build-swift -typecheck @%t.5.resp %s 2>&1 | %FileCheck %s -check-prefix=LONG
2929
// LONG: warning: result of call to 'abs' is unused
3030
// RUN: %empty-directory(%t/tmp)
31-
// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver %s @%t.5.resp -save-temps -o %t/main
32-
// RUN: ls %t/tmp/arguments-*.resp
31+
// RUN: env TMPDIR=%t/tmp/ TMP=%t/tmp/ %target-swiftc_driver %s @%t.5.resp -save-temps -o %t/main
32+
// RUN: ls %t/tmp | grep arguments.*resp
3333
// RUN: %target-build-swift -typecheck -v @%t.5.resp %s 2>&1 | %FileCheck %s -check-prefix=VERBOSE
34-
// VERBOSE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp # -frontend -typecheck -primary-file
35-
// RUN: not %target-swiftc_driver %s @%t.5.resp -Xfrontend -debug-crash-immediately 2>&1 | %FileCheck %s -check-prefix=CRASH
36-
// CRASH: Program arguments: {{[^ ]*}}swift -frontend -c -primary-file
34+
// VERBOSE: @{{[^ ]*}}arguments-{{[0-9a-zA-Z]+}}.resp{{"?}} # -frontend -typecheck -primary-file
35+
// RUN: not %target-swiftc_driver %s @%t.5.resp -Xfrontend -debug-crash-immediately 2>&1 | %FileCheck %s -check-prefix=TRACE
36+
// TRACE: Program arguments: {{[^ ]*}}swift{{c?(\.EXE)?}} -frontend -c -primary-file
37+
3738

3839
#if TEST0
3940
abs(-5)

tools/driver/driver.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/FrontendTool/FrontendTool.h"
3030
#include "llvm/ADT/SmallVector.h"
3131
#include "llvm/Support/CommandLine.h"
32+
#include "llvm/Support/ConvertUTF.h"
3233
#include "llvm/Support/Errno.h"
3334
#include "llvm/Support/FileSystem.h"
3435
#include "llvm/Support/Host.h"
@@ -45,6 +46,10 @@
4546
#include <memory>
4647
#include <stdlib.h>
4748

49+
#if defined(_WIN32)
50+
#include <windows.h>
51+
#endif
52+
4853
using namespace swift;
4954
using namespace swift::driver;
5055

@@ -174,6 +179,26 @@ static int run_driver(StringRef ExecName,
174179
}
175180

176181
int main(int argc_, const char **argv_) {
182+
#if defined(_WIN32)
183+
LPWSTR *wargv_ = CommandLineToArgvW(GetCommandLineW(), &argc_);
184+
std::vector<std::string> utf8Args;
185+
// We use UTF-8 as the internal character encoding. On Windows,
186+
// arguments passed to wmain are encoded in UTF-16
187+
for (int i = 0; i < argc_; i++) {
188+
const wchar_t *wideArg = wargv_[i];
189+
int wideArgLen = std::wcslen(wideArg);
190+
utf8Args.push_back("");
191+
llvm::ArrayRef<char> uRef((const char *)wideArg,
192+
(const char *)(wideArg + wideArgLen));
193+
llvm::convertUTF16ToUTF8String(uRef, utf8Args[i]);
194+
}
195+
196+
std::vector<const char *> utf8CStrs;
197+
std::transform(utf8Args.begin(), utf8Args.end(),
198+
std::back_inserter(utf8CStrs),
199+
std::mem_fn(&std::string::c_str));
200+
argv_ = utf8CStrs.data();
201+
#endif
177202
// Expand any response files in the command line argument vector - arguments
178203
// may be passed through response files in the event of command line length
179204
// restrictions.
@@ -182,17 +207,22 @@ int main(int argc_, const char **argv_) {
182207
llvm::StringSaver Saver(Allocator);
183208
llvm::cl::ExpandResponseFiles(
184209
Saver,
185-
llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows() ?
186-
llvm::cl::TokenizeWindowsCommandLine :
187-
llvm::cl::TokenizeGNUCommandLine,
210+
llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows()
211+
? llvm::cl::TokenizeWindowsCommandLine
212+
: llvm::cl::TokenizeGNUCommandLine,
188213
ExpandedArgs);
189214

190215
// Initialize the stack trace using the parsed argument vector with expanded
191216
// response files.
192-
int ExpandedArgc = ExpandedArgs.size();
193-
const char **ExpandedArgv = ExpandedArgs.data();
194-
PROGRAM_START(ExpandedArgc, ExpandedArgv);
195-
ArrayRef<const char *> argv(ExpandedArgv, ExpandedArgc);
217+
218+
// PROGRAM_START/InitLLVM overwrites the passed in arguments with UTF-8
219+
// versions of them on Windows. This also has the effect of overwriting the
220+
// response file expansion. Since we handle the UTF-8 conversion above, we
221+
// pass in a copy and throw away the modifications.
222+
int ThrowawayExpandedArgc = ExpandedArgs.size();
223+
const char **ThrowawayExpandedArgv = ExpandedArgs.data();
224+
PROGRAM_START(ThrowawayExpandedArgc, ThrowawayExpandedArgv);
225+
ArrayRef<const char *> argv(ExpandedArgs);
196226

197227
// Check if this invocation should execute a subcommand.
198228
StringRef ExecName = llvm::sys::path::stem(argv[0]);

0 commit comments

Comments
 (0)