Skip to content

Commit ffc990f

Browse files
committed
[driver/sourcekit] Avoid creating temporary output files in TMPDIR
When producing frontend arguments for sourcekitd, force the output mode to -typecheck so that we do not create any temporary output files in the driver. Previously, any sourcekitd operation that created a compiler invocation would create 0-sized .o file inside $TMPDIR that would never be cleaned up. The new swift-driver project handles temporaries much better as VirtualPath, and should not need this approach. rdar://62366123
1 parent 0c403fe commit ffc990f

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

include/swift/Driver/FrontendUtil.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,18 @@ namespace driver {
3333
/// \param Action Called with the list of frontend arguments if there were no
3434
/// errors in processing \p ArgList. This is a callback rather than a return
3535
/// value to avoid copying the arguments more than necessary.
36+
/// \param ForceNoOutputs If true, override the output mode to "-typecheck" and
37+
/// produce no outputs. For example, this disables "-emit-module" and "-c" and
38+
/// prevents the creation of temporary files.
3639
///
3740
/// \returns True on error, or if \p Action returns true.
3841
///
3942
/// \note This function is not intended to create invocations which are
4043
/// suitable for use in REPL or immediate modes.
4144
bool getSingleFrontendInvocationFromDriverArguments(
4245
ArrayRef<const char *> ArgList, DiagnosticEngine &Diags,
43-
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action);
46+
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action,
47+
bool ForceNoOutputs = false);
4448

4549
} // end namespace driver
4650
} // end namespace swift

lib/Driver/FrontendUtil.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ using namespace swift::driver;
2525

2626
bool swift::driver::getSingleFrontendInvocationFromDriverArguments(
2727
ArrayRef<const char *> Argv, DiagnosticEngine &Diags,
28-
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action) {
28+
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action,
29+
bool ForceNoOutputs) {
2930
SmallVector<const char *, 16> Args;
3031
Args.push_back("<swiftc>"); // FIXME: Remove dummy argument.
3132
Args.insert(Args.end(), Argv.begin(), Argv.end());
@@ -57,6 +58,25 @@ bool swift::driver::getSingleFrontendInvocationFromDriverArguments(
5758
if (Diags.hadAnyError())
5859
return true;
5960

61+
if (ForceNoOutputs) {
62+
// Clear existing output modes.
63+
ArgList->eraseArg(options::OPT_modes_Group);
64+
// Disable other output options that conflict with -typecheck.
65+
ArgList->eraseArg(options::OPT_emit_module);
66+
ArgList->eraseArg(options::OPT_emit_module_path);
67+
ArgList->eraseArg(options::OPT_emit_module_source_info_path);
68+
ArgList->eraseArg(options::OPT_emit_module_interface);
69+
ArgList->eraseArg(options::OPT_emit_module_interface_path);
70+
ArgList->eraseArg(options::OPT_emit_objc_header);
71+
ArgList->eraseArg(options::OPT_emit_objc_header_path);
72+
73+
unsigned index = ArgList->MakeIndex("-typecheck");
74+
// Takes ownership of the Arg.
75+
ArgList->append(new llvm::opt::Arg(
76+
TheDriver.getOpts().getOption(options::OPT_typecheck),
77+
ArgList->getArgString(index), index));
78+
}
79+
6080
std::unique_ptr<ToolChain> TC = TheDriver.buildToolChain(*ArgList);
6181
if (Diags.hadAnyError())
6282
return true;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// REQUIRES: shell
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=syntax-map %s
5+
// RUN: ls %t/ | count 0
6+
7+
// RUN: %empty-directory(%t)
8+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=syntax-map %s -- %s
9+
// RUN: ls %t/ | count 0
10+
11+
// RUN: %empty-directory(%t)
12+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=syntax-map %s -- %s -c -o %t/foo.o
13+
// RUN: ls %t/ | count 0
14+
15+
// RUN: %empty-directory(%t)
16+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=sema %s -- %s
17+
// RUN: ls %t/ | count 0
18+
19+
// RUN: %empty-directory(%t)
20+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=sema %s -- %s -c -o %t/foo.o
21+
// RUN: ls %t/ | count 0
22+
23+
// RUN: %empty-directory(%t)
24+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=sema %s -- %s -emit-module -module-name main -emit-module-path %t/main.swiftmodule -emit-module-interface -enable-library-evolution -emit-module-interface-path %t/main.swiftinterface -emit-objc-header -emit-objc-header-path %t/main.h -c -o %t/foo.o
25+
// RUN: ls %t/ | count 0
26+
27+
// RUN: %empty-directory(%t)
28+
// RUN: env TMPDIR=%t __XPC_TMPDIR=%t %sourcekitd-test -req=sema %s -- %s -emit-module -module-name main -emit-module-path %t/main.swiftmodule -emit-executable -o %t/foo
29+
// RUN: ls %t/ | count 0

tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ bool SwiftASTManager::initCompilerInvocation(
507507
bool HadError = driver::getSingleFrontendInvocationFromDriverArguments(
508508
Args, Diags, [&](ArrayRef<const char *> FrontendArgs) {
509509
return Invocation.parseArgs(FrontendArgs, Diags);
510-
});
510+
}, /*ForceNoOutputs=*/true);
511511

512512
// Remove the StreamDiagConsumer as it's no longer needed.
513513
Diags.removeConsumer(DiagConsumer);

0 commit comments

Comments
 (0)