mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/master' into master-next
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include "swift/Option/SanitizerOptions.h"
|
||||
#include "swift/Parse/Lexer.h"
|
||||
#include "swift/Config.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
@@ -1843,7 +1844,8 @@ static StringRef getOutputFilename(Compilation &C,
|
||||
|
||||
static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
|
||||
types::ID outputType, const OutputInfo &OI,
|
||||
const TypeToPathMap *outputMap) {
|
||||
const TypeToPathMap *outputMap,
|
||||
StringRef outputPath = StringRef()) {
|
||||
StringRef outputMapPath;
|
||||
if (outputMap) {
|
||||
auto iter = outputMap->find(outputType);
|
||||
@@ -1854,6 +1856,8 @@ static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
|
||||
if (!outputMapPath.empty()) {
|
||||
// Prefer a path from the OutputMap.
|
||||
output.setAdditionalOutputForType(outputType, outputMapPath);
|
||||
} else if (!outputPath.empty()) {
|
||||
output.setAdditionalOutputForType(outputType, outputPath);
|
||||
} else {
|
||||
// Put the auxiliary output file next to the primary output file.
|
||||
llvm::SmallString<128> path;
|
||||
@@ -1873,6 +1877,58 @@ static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
|
||||
}
|
||||
}
|
||||
|
||||
static void addDiagFileOutputForPersistentPCHAction(Compilation &C,
|
||||
const GeneratePCHJobAction *JA,
|
||||
CommandOutput &output,
|
||||
const OutputInfo &OI,
|
||||
const TypeToPathMap *outputMap,
|
||||
DiagnosticEngine &diags) {
|
||||
assert(JA->isPersistentPCH());
|
||||
|
||||
// For a persistent PCH we don't use an output, the frontend determines
|
||||
// the filename to use for the PCH. For the diagnostics file, try to
|
||||
// determine an invocation-specific path inside the directory where the
|
||||
// PCH is going to be written, and fallback to a temporary file if we
|
||||
// cannot determine such a path.
|
||||
|
||||
StringRef pchOutDir = JA->getPersistentPCHDir();
|
||||
StringRef headerPath = output.getBaseInput(JA->getInputIndex());
|
||||
StringRef stem = llvm::sys::path::stem(headerPath);
|
||||
StringRef suffix = types::getTypeTempSuffix(types::TY_SerializedDiagnostics);
|
||||
SmallString<256> outPathBuf;
|
||||
|
||||
if (const Arg *A = C.getArgs().getLastArg(options::OPT_emit_module_path)) {
|
||||
// The module file path is unique for a specific module and architecture
|
||||
// (it won't be concurrently written to) so we can use the path as hash
|
||||
// for determining the filename to use for the diagnostic file.
|
||||
StringRef ModuleOutPath = A->getValue();
|
||||
outPathBuf = pchOutDir;
|
||||
llvm::sys::path::append(outPathBuf, stem);
|
||||
outPathBuf += '-';
|
||||
auto code = llvm::hash_value(ModuleOutPath);
|
||||
outPathBuf += llvm::APInt(64, code).toString(36, /*Signed=*/false);
|
||||
llvm::sys::path::replace_extension(outPathBuf, suffix);
|
||||
}
|
||||
|
||||
if (outPathBuf.empty()) {
|
||||
// Fallback to creating a temporary file.
|
||||
std::error_code EC =
|
||||
llvm::sys::fs::createTemporaryFile(stem, suffix, outPathBuf);
|
||||
if (EC) {
|
||||
diags.diagnose(SourceLoc(),
|
||||
diag::error_unable_to_make_temporary_file,
|
||||
EC.message());
|
||||
return;
|
||||
}
|
||||
C.addTemporaryFile(outPathBuf.str());
|
||||
}
|
||||
|
||||
if (!outPathBuf.empty()) {
|
||||
addAuxiliaryOutput(C, output, types::TY_SerializedDiagnostics, OI,
|
||||
outputMap, outPathBuf.str());
|
||||
}
|
||||
}
|
||||
|
||||
/// If the file at \p input has not been modified since the last build (i.e. its
|
||||
/// mtime has not changed), adjust the Job's condition accordingly.
|
||||
static void
|
||||
@@ -2107,8 +2163,14 @@ Job *Driver::buildJobsForAction(Compilation &C, const JobAction *JA,
|
||||
if (isa<CompileJobAction>(JA) || isa<GeneratePCHJobAction>(JA)) {
|
||||
// Choose the serialized diagnostics output path.
|
||||
if (C.getArgs().hasArg(options::OPT_serialize_diagnostics)) {
|
||||
addAuxiliaryOutput(C, *Output, types::TY_SerializedDiagnostics, OI,
|
||||
OutputMap);
|
||||
auto pchJA = dyn_cast<GeneratePCHJobAction>(JA);
|
||||
if (pchJA && pchJA->isPersistentPCH()) {
|
||||
addDiagFileOutputForPersistentPCHAction(C, pchJA, *Output, OI,
|
||||
OutputMap, Diags);
|
||||
} else {
|
||||
addAuxiliaryOutput(C, *Output, types::TY_SerializedDiagnostics, OI,
|
||||
OutputMap);
|
||||
}
|
||||
|
||||
// Remove any existing diagnostics files so that clients can detect their
|
||||
// presence to determine if a command was run.
|
||||
|
||||
Reference in New Issue
Block a user