Skip to content

Commit ffd9e95

Browse files
authored
Merge pull request swiftlang#10158 from akyrtzi/persistent-pch-diag-file
[driver] For the persistent bridging PCH job action, make sure to pass a serialized diagnostics path in the PCH output directory
2 parents e7da527 + 563a37f commit ffd9e95

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

lib/Driver/Driver.cpp

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "swift/Option/SanitizerOptions.h"
3636
#include "swift/Parse/Lexer.h"
3737
#include "swift/Config.h"
38+
#include "llvm/ADT/APInt.h"
3839
#include "llvm/ADT/DenseSet.h"
3940
#include "llvm/ADT/STLExtras.h"
4041
#include "llvm/ADT/SmallString.h"
@@ -1844,7 +1845,8 @@ static StringRef getOutputFilename(Compilation &C,
18441845

18451846
static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
18461847
types::ID outputType, const OutputInfo &OI,
1847-
const TypeToPathMap *outputMap) {
1848+
const TypeToPathMap *outputMap,
1849+
StringRef outputPath = StringRef()) {
18481850
StringRef outputMapPath;
18491851
if (outputMap) {
18501852
auto iter = outputMap->find(outputType);
@@ -1855,6 +1857,8 @@ static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
18551857
if (!outputMapPath.empty()) {
18561858
// Prefer a path from the OutputMap.
18571859
output.setAdditionalOutputForType(outputType, outputMapPath);
1860+
} else if (!outputPath.empty()) {
1861+
output.setAdditionalOutputForType(outputType, outputPath);
18581862
} else {
18591863
// Put the auxiliary output file next to the primary output file.
18601864
llvm::SmallString<128> path;
@@ -1874,6 +1878,58 @@ static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
18741878
}
18751879
}
18761880

1881+
static void addDiagFileOutputForPersistentPCHAction(Compilation &C,
1882+
const GeneratePCHJobAction *JA,
1883+
CommandOutput &output,
1884+
const OutputInfo &OI,
1885+
const TypeToPathMap *outputMap,
1886+
DiagnosticEngine &diags) {
1887+
assert(JA->isPersistentPCH());
1888+
1889+
// For a persistent PCH we don't use an output, the frontend determines
1890+
// the filename to use for the PCH. For the diagnostics file, try to
1891+
// determine an invocation-specific path inside the directory where the
1892+
// PCH is going to be written, and fallback to a temporary file if we
1893+
// cannot determine such a path.
1894+
1895+
StringRef pchOutDir = JA->getPersistentPCHDir();
1896+
StringRef headerPath = output.getBaseInput(JA->getInputIndex());
1897+
StringRef stem = llvm::sys::path::stem(headerPath);
1898+
StringRef suffix = types::getTypeTempSuffix(types::TY_SerializedDiagnostics);
1899+
SmallString<256> outPathBuf;
1900+
1901+
if (const Arg *A = C.getArgs().getLastArg(options::OPT_emit_module_path)) {
1902+
// The module file path is unique for a specific module and architecture
1903+
// (it won't be concurrently written to) so we can use the path as hash
1904+
// for determining the filename to use for the diagnostic file.
1905+
StringRef ModuleOutPath = A->getValue();
1906+
outPathBuf = pchOutDir;
1907+
llvm::sys::path::append(outPathBuf, stem);
1908+
outPathBuf += '-';
1909+
auto code = llvm::hash_value(ModuleOutPath);
1910+
outPathBuf += llvm::APInt(64, code).toString(36, /*Signed=*/false);
1911+
llvm::sys::path::replace_extension(outPathBuf, suffix);
1912+
}
1913+
1914+
if (outPathBuf.empty()) {
1915+
// Fallback to creating a temporary file.
1916+
std::error_code EC =
1917+
llvm::sys::fs::createTemporaryFile(stem, suffix, outPathBuf);
1918+
if (EC) {
1919+
diags.diagnose(SourceLoc(),
1920+
diag::error_unable_to_make_temporary_file,
1921+
EC.message());
1922+
return;
1923+
}
1924+
C.addTemporaryFile(outPathBuf.str());
1925+
}
1926+
1927+
if (!outPathBuf.empty()) {
1928+
addAuxiliaryOutput(C, output, types::TY_SerializedDiagnostics, OI,
1929+
outputMap, outPathBuf.str());
1930+
}
1931+
}
1932+
18771933
/// If the file at \p input has not been modified since the last build (i.e. its
18781934
/// mtime has not changed), adjust the Job's condition accordingly.
18791935
static void
@@ -2108,8 +2164,14 @@ Job *Driver::buildJobsForAction(Compilation &C, const JobAction *JA,
21082164
if (isa<CompileJobAction>(JA) || isa<GeneratePCHJobAction>(JA)) {
21092165
// Choose the serialized diagnostics output path.
21102166
if (C.getArgs().hasArg(options::OPT_serialize_diagnostics)) {
2111-
addAuxiliaryOutput(C, *Output, types::TY_SerializedDiagnostics, OI,
2112-
OutputMap);
2167+
auto pchJA = dyn_cast<GeneratePCHJobAction>(JA);
2168+
if (pchJA && pchJA->isPersistentPCH()) {
2169+
addDiagFileOutputForPersistentPCHAction(C, pchJA, *Output, OI,
2170+
OutputMap, Diags);
2171+
} else {
2172+
addAuxiliaryOutput(C, *Output, types::TY_SerializedDiagnostics, OI,
2173+
OutputMap);
2174+
}
21132175

21142176
// Remove any existing diagnostics files so that clients can detect their
21152177
// presence to determine if a command was run.

test/Driver/bridging-pch.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
// PERSISTENT-YESPCHJOB: {{.*}}swift -frontend {{.*}} -emit-pch -pch-output-dir {{.*}}/pch
4343
// PERSISTENT-YESPCHJOB: {{.*}}swift -frontend {{.*}} -import-objc-header {{.*}}bridging-header.h -pch-output-dir {{.*}}/pch -pch-disable-validation
4444

45+
// RUN: %swiftc_driver -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -serialize-diagnostics %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG1
46+
// PERSISTENT-YESPCHJOB-DIAG1: {{.*}}swift -frontend {{.*}} -serialize-diagnostics-path {{.*}}bridging-header-{{.*}}.dia {{.*}} -emit-pch -pch-output-dir {{.*}}/pch
47+
48+
// RUN: %swiftc_driver -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch-out-dir -serialize-diagnostics %s -emit-module -emit-module-path /module-path-dir 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG2
49+
// PERSISTENT-YESPCHJOB-DIAG2: {{.*}}swift -frontend {{.*}} -serialize-diagnostics-path {{.*}}/pch-out-dir/bridging-header-{{.*}}.dia {{.*}} -emit-pch -pch-output-dir {{.*}}/pch-out-dir
50+
4551
// RUN: %swiftc_driver -typecheck -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -parseable-output -driver-skip-execution %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-OUTPUT
4652
// PERSISTENT-OUTPUT-NOT: "outputs": [
4753

0 commit comments

Comments
 (0)