From 91e31970b662a4b0167821c333b4872e72008adf Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Tue, 2 Aug 2016 17:55:37 -0700 Subject: [PATCH] [Driver] Make sure to rebuild dependents when a dirty file fails. Otherwise we get into a situation like this: 1. Change made to the interface of file A.swift that also causes an error in A.swift. 2. Fixing the error in A.swift does not affect A.swift's interface. 3. File B.swift that depends on A.swift is not rebuilt, since the most recent change to A.swift did not change its interface. To fix this, mark downstream files as needing to be rebuilt even when a compilation job fails with errors. Additionally, attempt to be extra conservative when there's a crash. rdar://problem/25405605 --- lib/Driver/Compilation.cpp | 101 ++++++++++++------ lib/Driver/Driver.cpp | 54 +++++----- .../Inputs/crash-simple/crash.swift | 2 + .../Inputs/crash-simple/main.swift | 2 + .../Inputs/crash-simple/other.swift | 2 + .../Inputs/crash-simple/output.json | 17 +++ .../Inputs/fail-with-bad-deps/bad.swift | 4 + .../Inputs/fail-with-bad-deps/bad.swiftdeps | 3 + .../fail-with-bad-deps/depends-on-bad.swift | 3 + .../depends-on-bad.swiftdeps | 3 + .../fail-with-bad-deps/depends-on-main.swift | 3 + .../depends-on-main.swiftdeps | 3 + .../Inputs/fail-with-bad-deps/main.swift | 3 + .../Inputs/fail-with-bad-deps/main.swiftdeps | 3 + .../Inputs/fail-with-bad-deps/output.json | 21 ++++ .../Inputs/update-dependencies-bad.py | 23 +++- .../bindings-build-record-options.swift | 27 +++-- .../Dependencies/bindings-build-record.swift | 11 +- test/Driver/Dependencies/crash-added.swift | 30 ++++++ test/Driver/Dependencies/crash-new.swift | 44 ++++++++ test/Driver/Dependencies/crash-simple.swift | 23 ++++ test/Driver/Dependencies/fail-added.swift | 30 ++++++ .../Dependencies/fail-interface-hash.swift | 2 +- test/Driver/Dependencies/fail-new.swift | 15 ++- .../Dependencies/fail-with-bad-deps.swift | 47 ++++++++ .../Inputs/rdar25405605/helper-1.swift | 13 +++ .../Inputs/rdar25405605/helper-2.swift | 14 +++ .../Inputs/rdar25405605/helper-3.swift | 15 +++ .../Inputs/rdar25405605/output.json | 13 +++ .../Driver/Dependencies/rdar25405605.swift | 81 ++++++++++++++ 30 files changed, 533 insertions(+), 79 deletions(-) create mode 100644 test/Driver/Dependencies/Inputs/crash-simple/crash.swift create mode 100644 test/Driver/Dependencies/Inputs/crash-simple/main.swift create mode 100644 test/Driver/Dependencies/Inputs/crash-simple/other.swift create mode 100644 test/Driver/Dependencies/Inputs/crash-simple/output.json create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swift create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swiftdeps create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swift create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swiftdeps create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swift create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swiftdeps create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swift create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swiftdeps create mode 100644 test/Driver/Dependencies/Inputs/fail-with-bad-deps/output.json create mode 100644 test/Driver/Dependencies/crash-added.swift create mode 100644 test/Driver/Dependencies/crash-new.swift create mode 100644 test/Driver/Dependencies/crash-simple.swift create mode 100644 test/Driver/Dependencies/fail-added.swift create mode 100644 test/Driver/Dependencies/fail-with-bad-deps.swift create mode 100644 validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-1.swift create mode 100644 validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-2.swift create mode 100644 validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-3.swift create mode 100644 validation-test/Driver/Dependencies/Inputs/rdar25405605/output.json create mode 100644 validation-test/Driver/Dependencies/rdar25405605.swift diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index bec468217b3bc..c790a22e71439 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -456,6 +456,70 @@ int Compilation::performJobsImpl() { llvm::errs() << Output; } + // In order to handle both old dependencies that have disappeared and new + // dependencies that have arisen, we need to reload the dependency file. + // Do this whether or not the build succeeded. + SmallVector Dependents; + if (getIncrementalBuildEnabled()) { + const CommandOutput &Output = FinishedCmd->getOutput(); + StringRef DependenciesFile = + Output.getAdditionalOutputForType(types::TY_SwiftDeps); + if (!DependenciesFile.empty() && + (ReturnCode == EXIT_SUCCESS || ReturnCode == EXIT_FAILURE)) { + bool wasCascading = DepGraph.isMarked(FinishedCmd); + + switch (DepGraph.loadFromPath(FinishedCmd, DependenciesFile)) { + case DependencyGraphImpl::LoadResult::HadError: + if (ReturnCode == EXIT_SUCCESS) { + disableIncrementalBuild(); + for (const Job *Cmd : DeferredCommands) + scheduleCommandIfNecessaryAndPossible(Cmd); + DeferredCommands.clear(); + Dependents.clear(); + } // else, let the next build handle it. + break; + case DependencyGraphImpl::LoadResult::UpToDate: + if (!wasCascading) + break; + SWIFT_FALLTHROUGH; + case DependencyGraphImpl::LoadResult::AffectsDownstream: + llvm::errs() << "DOWNSTREAM " << ReturnCode << "\n"; + DepGraph.markTransitive(Dependents, FinishedCmd); + break; + } + } else { + // If there's a crash, assume the worst. + switch (FinishedCmd->getCondition()) { + case Job::Condition::NewlyAdded: + // The job won't be treated as newly added next time. Conservatively + // mark it as affecting other jobs, because some of them may have + // completed already. + DepGraph.markTransitive(Dependents, FinishedCmd); + break; + case Job::Condition::Always: + // This applies to non-incremental tasks as well, but any incremental + // task that shows up here has already been marked. + break; + case Job::Condition::RunWithoutCascading: + // If this file changed, it might have been a non-cascading change and + // it might not. Unfortunately, the interface hash has been updated or + // compromised, so we don't actually know anymore; we have to + // conservatively assume the changes could affect other files. + DepGraph.markTransitive(Dependents, FinishedCmd); + break; + case Job::Condition::CheckDependencies: + // If the only reason we're running this is because something else + // changed, then we can trust the dependency graph as to whether it's + // a cascading or non-cascading change. That is, if whatever /caused/ + // the error isn't supposed to affect other files, and whatever + // /fixes/ the error isn't supposed to affect other files, then + // there's no need to recompile any other inputs. If either of those + // are false, we /do/ need to recompile other inputs. + break; + } + } + } + if (ReturnCode != EXIT_SUCCESS) { // The task failed, so return true without performing any further // dependency analysis. @@ -481,39 +545,10 @@ int Compilation::performJobsImpl() { // might have been blocked. markFinished(FinishedCmd); - // In order to handle both old dependencies that have disappeared and new - // dependencies that have arisen, we need to reload the dependency file. - if (getIncrementalBuildEnabled()) { - const CommandOutput &Output = FinishedCmd->getOutput(); - StringRef DependenciesFile = - Output.getAdditionalOutputForType(types::TY_SwiftDeps); - if (!DependenciesFile.empty()) { - SmallVector Dependents; - bool wasCascading = DepGraph.isMarked(FinishedCmd); - - switch (DepGraph.loadFromPath(FinishedCmd, DependenciesFile)) { - case DependencyGraphImpl::LoadResult::HadError: - disableIncrementalBuild(); - for (const Job *Cmd : DeferredCommands) - scheduleCommandIfNecessaryAndPossible(Cmd); - DeferredCommands.clear(); - Dependents.clear(); - break; - case DependencyGraphImpl::LoadResult::UpToDate: - if (!wasCascading) - break; - SWIFT_FALLTHROUGH; - case DependencyGraphImpl::LoadResult::AffectsDownstream: - DepGraph.markTransitive(Dependents, FinishedCmd); - break; - } - - for (const Job *Cmd : Dependents) { - DeferredCommands.erase(Cmd); - noteBuilding(Cmd, "because of dependencies discovered later"); - scheduleCommandIfNecessaryAndPossible(Cmd); - } - } + for (const Job *Cmd : Dependents) { + DeferredCommands.erase(Cmd); + noteBuilding(Cmd, "because of dependencies discovered later"); + scheduleCommandIfNecessaryAndPossible(Cmd); } return TaskFinishedResponse::ContinueExecution; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 6c380b622c861..1019f9ef044ee 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1604,36 +1604,40 @@ handleCompileJobCondition(Job *J, CompileJobAction::InputInfo inputInfo, return; } - if (!alwaysRebuildDependents) { - // Default all non-newly added files to being rebuilt without cascading. - J->setCondition(Job::Condition::RunWithoutCascading); - } - + bool hasValidModTime = false; llvm::sys::fs::file_status inputStatus; - if (llvm::sys::fs::status(input, inputStatus)) - return; - - J->setInputModTime(inputStatus.getLastModificationTime()); - if (J->getInputModTime() != inputInfo.previousModTime) - return; + if (!llvm::sys::fs::status(input, inputStatus)) { + J->setInputModTime(inputStatus.getLastModificationTime()); + hasValidModTime = true; + } Job::Condition condition; - switch (inputInfo.status) { - case CompileJobAction::InputInfo::UpToDate: - if (!llvm::sys::fs::exists(J->getOutput().getPrimaryOutputFilename())) + if (!hasValidModTime || J->getInputModTime() != inputInfo.previousModTime) { + if (alwaysRebuildDependents || + inputInfo.status == CompileJobAction::InputInfo::NeedsCascadingBuild) { + condition = Job::Condition::Always; + } else { condition = Job::Condition::RunWithoutCascading; - else - condition = Job::Condition::CheckDependencies; - break; - case CompileJobAction::InputInfo::NeedsCascadingBuild: - condition = Job::Condition::Always; - break; - case CompileJobAction::InputInfo::NeedsNonCascadingBuild: - condition = Job::Condition::RunWithoutCascading; - break; - case CompileJobAction::InputInfo::NewlyAdded: - llvm_unreachable("handled above"); + } + } else { + switch (inputInfo.status) { + case CompileJobAction::InputInfo::UpToDate: + if (!llvm::sys::fs::exists(J->getOutput().getPrimaryOutputFilename())) + condition = Job::Condition::RunWithoutCascading; + else + condition = Job::Condition::CheckDependencies; + break; + case CompileJobAction::InputInfo::NeedsCascadingBuild: + condition = Job::Condition::Always; + break; + case CompileJobAction::InputInfo::NeedsNonCascadingBuild: + condition = Job::Condition::RunWithoutCascading; + break; + case CompileJobAction::InputInfo::NewlyAdded: + llvm_unreachable("handled above"); + } } + J->setCondition(condition); } diff --git a/test/Driver/Dependencies/Inputs/crash-simple/crash.swift b/test/Driver/Dependencies/Inputs/crash-simple/crash.swift new file mode 100644 index 0000000000000..7e7daa298c540 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/crash-simple/crash.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +provides-top-level: [a] diff --git a/test/Driver/Dependencies/Inputs/crash-simple/main.swift b/test/Driver/Dependencies/Inputs/crash-simple/main.swift new file mode 100644 index 0000000000000..c6dd8d475b207 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/crash-simple/main.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +depends-top-level: [a] diff --git a/test/Driver/Dependencies/Inputs/crash-simple/other.swift b/test/Driver/Dependencies/Inputs/crash-simple/other.swift new file mode 100644 index 0000000000000..33392ce138612 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/crash-simple/other.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +depends-top-level: [!private a] diff --git a/test/Driver/Dependencies/Inputs/crash-simple/output.json b/test/Driver/Dependencies/Inputs/crash-simple/output.json new file mode 100644 index 0000000000000..1f7532dc86406 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/crash-simple/output.json @@ -0,0 +1,17 @@ +{ + "./main.swift": { + "object": "./main.o", + "swift-dependencies": "./main.swiftdeps" + }, + "./crash.swift": { + "object": "./crash.o", + "swift-dependencies": "./crash.swiftdeps" + }, + "./other.swift": { + "object": "./other.o", + "swift-dependencies": "./other.swiftdeps" + }, + "": { + "swift-dependencies": "./main~buildrecord.swiftdeps" + } +} diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swift b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swift new file mode 100644 index 0000000000000..0f05e70d14710 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swift @@ -0,0 +1,4 @@ +# Dependencies after compilation: +provides-top-level: [bad] +interface-hash: "after" +garbage: "" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swiftdeps b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swiftdeps new file mode 100644 index 0000000000000..923f6689ba1a5 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/bad.swiftdeps @@ -0,0 +1,3 @@ +# Dependencies before compilation: +provides-top-level: [bad] +interface-hash: "before" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swift b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swift new file mode 100644 index 0000000000000..415ec3b051000 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swift @@ -0,0 +1,3 @@ +# Dependencies after compilation: +depends-top-level: [bad] +interface-hash: "after" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swiftdeps b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swiftdeps new file mode 100644 index 0000000000000..97afde93b75ca --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-bad.swiftdeps @@ -0,0 +1,3 @@ +# Dependencies before compilation: +depends-top-level: [bad] +interface-hash: "before" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swift b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swift new file mode 100644 index 0000000000000..2b781b861cb7e --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swift @@ -0,0 +1,3 @@ +# Dependencies after compilation: +depends-top-level: [main] +interface-hash: "after" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swiftdeps b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swiftdeps new file mode 100644 index 0000000000000..cd50d25b878a7 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/depends-on-main.swiftdeps @@ -0,0 +1,3 @@ +# Dependencies before compilation: +depends-top-level: [main] +interface-hash: "before" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swift b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swift new file mode 100644 index 0000000000000..5b5f8d7f3346f --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swift @@ -0,0 +1,3 @@ +# Dependencies after compilation: +provides-top-level: [main] +interface-hash: "after" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swiftdeps b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swiftdeps new file mode 100644 index 0000000000000..0ec59e418937a --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/main.swiftdeps @@ -0,0 +1,3 @@ +# Dependencies before compilation: +provides-top-level: [main] +interface-hash: "before" diff --git a/test/Driver/Dependencies/Inputs/fail-with-bad-deps/output.json b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/output.json new file mode 100644 index 0000000000000..7078694c2f183 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/fail-with-bad-deps/output.json @@ -0,0 +1,21 @@ +{ + "./main.swift": { + "object": "./main.o", + "swift-dependencies": "./main.swiftdeps" + }, + "./bad.swift": { + "object": "./bad.o", + "swift-dependencies": "./bad.swiftdeps" + }, + "./depends-on-main.swift": { + "object": "./depends-on-main.o", + "swift-dependencies": "./depends-on-main.swiftdeps" + }, + "./depends-on-bad.swift": { + "object": "./depends-on-bad.o", + "swift-dependencies": "./depends-on-bad.swiftdeps" + }, + "": { + "swift-dependencies": "./main~buildrecord.swiftdeps" + } +} diff --git a/test/Driver/Dependencies/Inputs/update-dependencies-bad.py b/test/Driver/Dependencies/Inputs/update-dependencies-bad.py index 058428df7f65f..530ba73080955 100755 --- a/test/Driver/Dependencies/Inputs/update-dependencies-bad.py +++ b/test/Driver/Dependencies/Inputs/update-dependencies-bad.py @@ -11,23 +11,38 @@ # # ---------------------------------------------------------------------------- # -# Fails if the input file is named "bad.swift"; otherwise dispatches to -# update-dependencies.py. +# Fails if the input file is named "bad.swift" or "crash.swift"; otherwise +# dispatches to update-dependencies.py. "crash.swift" gives an exit code +# other than 1. # # ---------------------------------------------------------------------------- from __future__ import print_function import os +import shutil import sys assert sys.argv[1] == '-frontend' primaryFile = sys.argv[sys.argv.index('-primary-file') + 1] -if os.path.basename(primaryFile) == 'bad.swift': +if (os.path.basename(primaryFile) == 'bad.swift' or + os.path.basename(primaryFile) == 'crash.swift'): print("Handled", os.path.basename(primaryFile)) - sys.exit(1) + + # Replace the dependencies file with the input file. + try: + depsFile = sys.argv[sys.argv.index( + '-emit-reference-dependencies-path') + 1] + shutil.copyfile(primaryFile, depsFile) + except ValueError: + pass + + if os.path.basename(primaryFile) == 'bad.swift': + sys.exit(1) + else: + sys.exit(129) dir = os.path.dirname(os.path.abspath(__file__)) execfile(os.path.join(dir, "update-dependencies.py")) diff --git a/test/Driver/Dependencies/bindings-build-record-options.swift b/test/Driver/Dependencies/bindings-build-record-options.swift index 83a630f36ea6e..cffc3f1ab3442 100644 --- a/test/Driver/Dependencies/bindings-build-record-options.swift +++ b/test/Driver/Dependencies/bindings-build-record-options.swift @@ -1,12 +1,17 @@ // RUN: rm -rf %t && cp -r %S/Inputs/bindings-build-record/ %t // RUN: touch -t 201401240005 %t/* -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-INITIAL -// MUST-EXEC-NOT: warning -// MUST-EXEC: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading -// MUST-EXEC: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading -// MUST-EXEC: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: run-without-cascading +// MUST-EXEC-INITIAL-NOT: warning +// MUST-EXEC-INITIAL: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading +// MUST-EXEC-INITIAL: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading +// MUST-EXEC-INITIAL: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: run-without-cascading + +// MUST-EXEC-ALL-NOT: warning +// MUST-EXEC-ALL: inputs: ["./main.swift"], output: {{[{].*[}]$}} +// MUST-EXEC-ALL: inputs: ["./other.swift"], output: {{[{].*[}]$}} +// MUST-EXEC-ALL: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}} // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC @@ -19,28 +24,28 @@ // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings -serialize-diagnostics ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -serialize-diagnostics -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC -// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL // RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC // RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -DDEBUG -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC diff --git a/test/Driver/Dependencies/bindings-build-record.swift b/test/Driver/Dependencies/bindings-build-record.swift index c4d6ced29fbff..c9fa63a75b692 100644 --- a/test/Driver/Dependencies/bindings-build-record.swift +++ b/test/Driver/Dependencies/bindings-build-record.swift @@ -37,10 +37,15 @@ // RUN: %S/Inputs/touch.py 443865900 %t/* // RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=FILE-REMOVED -// FILE-REMOVED: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading -// FILE-REMOVED: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading +// FILE-REMOVED: inputs: ["./main.swift"], output: {{[{].*[}]$}} +// FILE-REMOVED: inputs: ["./other.swift"], output: {{[{].*[}]$}} // FILE-REMOVED-NOT: yet-another.swift // RUN: echo '{version: "bogus", inputs: {"./main.swift": [443865900, 0], "./other.swift": !private [443865900, 0], "./yet-another.swift": !dirty [443865900, 0]}}' > %t/main~buildrecord.swiftdeps -// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC +// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=INVALID-RECORD + +// INVALID-RECORD-NOT: warning +// INVALID-RECORD: inputs: ["./main.swift"], output: {{[{].*[}]$}} +// INVALID-RECORD: inputs: ["./other.swift"], output: {{[{].*[}]$}} +// INVALID-RECORD: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}} diff --git a/test/Driver/Dependencies/crash-added.swift b/test/Driver/Dependencies/crash-added.swift new file mode 100644 index 0000000000000..1f4f9786b6585 --- /dev/null +++ b/test/Driver/Dependencies/crash-added.swift @@ -0,0 +1,30 @@ +/// crash ==> main | crash --> other + +// RUN: rm -rf %t && cp -r %S/Inputs/crash-simple/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-INITIAL %s + +// CHECK-INITIAL-NOT: warning +// CHECK-INITIAL: Handled main.swift +// CHECK-INITIAL: Handled other.swift + +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift ./crash.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-ADDED %s +// RUN: FileCheck -check-prefix=CHECK-RECORD-ADDED %s < %t/main~buildrecord.swiftdeps + +// CHECK-ADDED-NOT: Handled +// CHECK-ADDED: Handled crash.swift +// CHECK-ADDED-NOT: Handled + +// CHECK-RECORD-ADDED-DAG: "./crash.swift": !dirty [ +// CHECK-RECORD-ADDED-DAG: "./main.swift": [ +// CHECK-RECORD-ADDED-DAG: "./other.swift": [ + + +// RUN: rm -rf %t && cp -r %S/Inputs/crash-simple/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-INITIAL %s + +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./crash.swift ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-ADDED %s +// RUN: FileCheck -check-prefix=CHECK-RECORD-ADDED %s < %t/main~buildrecord.swiftdeps diff --git a/test/Driver/Dependencies/crash-new.swift b/test/Driver/Dependencies/crash-new.swift new file mode 100644 index 0000000000000..4bb967c9edceb --- /dev/null +++ b/test/Driver/Dependencies/crash-new.swift @@ -0,0 +1,44 @@ +/// crash ==> main | crash --> other + +// RUN: rm -rf %t && cp -r %S/Inputs/crash-simple/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s +// CHECK-NOT: warning +// CHECK: Handled main.swift +// CHECK: Handled crash.swift +// CHECK-NOT: Handled other.swift + +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-BAD-ONLY %s + +// CHECK-BAD-ONLY-NOT: warning +// CHECK-BAD-ONLY-NOT: Handled +// CHECK-BAD-ONLY: Handled crash.swift +// CHECK-BAD-ONLY-NOT: Handled + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-OKAY %s +// CHECK-OKAY: Handled main.swift +// CHECK-OKAY: Handled crash.swift +// CHECK-OKAY: Handled other.swift +// CHECK-OKAY-NOT: Handled + +// RUN: touch -t 201401240006 %t/crash.swift +// RUN: rm %t/crash.swiftdeps +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s + +// RUN: touch -t 201401240005 %t/* +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-OKAY-2 %s + +// CHECK-OKAY-2: Handled crash.swift +// CHECK-OKAY-2: Handled other.swift +// CHECK-OKAY-2: Handled main.swift + +// RUN: touch -t 201401240006 %t/main.swift +// RUN: rm %t/main.swiftdeps +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s + +// RUN: touch -t 201401240005 %t/* +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-OKAY %s +// RUN: touch -t 201401240006 %t/other.swift +// RUN: rm %t/other.swiftdeps +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s diff --git a/test/Driver/Dependencies/crash-simple.swift b/test/Driver/Dependencies/crash-simple.swift new file mode 100644 index 0000000000000..ce0eb9e04045f --- /dev/null +++ b/test/Driver/Dependencies/crash-simple.swift @@ -0,0 +1,23 @@ +/// crash ==> main | crash --> other + +// RUN: rm -rf %t && cp -r %S/Inputs/crash-simple/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-FIRST %s + +// CHECK-FIRST-NOT: warning +// CHECK-FIRST: Handled main.swift +// CHECK-FIRST: Handled crash.swift +// CHECK-FIRST: Handled other.swift + +// RUN: touch -t 201401240006 %t/crash.swift +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./crash.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-SECOND %s +// RUN: FileCheck -check-prefix=CHECK-RECORD %s < %t/main~buildrecord.swiftdeps + +// CHECK-SECOND: Handled crash.swift +// CHECK-SECOND-NOT: Handled main.swift +// CHECK-SECOND-NOT: Handled other.swift + +// CHECK-RECORD-DAG: "./crash.swift": !dirty [ +// CHECK-RECORD-DAG: "./main.swift": !dirty [ +// CHECK-RECORD-DAG: "./other.swift": !private [ diff --git a/test/Driver/Dependencies/fail-added.swift b/test/Driver/Dependencies/fail-added.swift new file mode 100644 index 0000000000000..a333078fcfb5c --- /dev/null +++ b/test/Driver/Dependencies/fail-added.swift @@ -0,0 +1,30 @@ +/// bad ==> main | bad --> other + +// RUN: rm -rf %t && cp -r %S/Inputs/fail-simple/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-INITIAL %s + +// CHECK-INITIAL-NOT: warning +// CHECK-INITIAL: Handled main.swift +// CHECK-INITIAL: Handled other.swift + +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift ./bad.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-ADDED %s +// RUN: FileCheck -check-prefix=CHECK-RECORD-ADDED %s < %t/main~buildrecord.swiftdeps + +// CHECK-ADDED-NOT: Handled +// CHECK-ADDED: Handled bad.swift +// CHECK-ADDED-NOT: Handled + +// CHECK-RECORD-ADDED-DAG: "./bad.swift": !dirty [ +// CHECK-RECORD-ADDED-DAG: "./main.swift": [ +// CHECK-RECORD-ADDED-DAG: "./other.swift": [ + + +// RUN: rm -rf %t && cp -r %S/Inputs/fail-simple/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-INITIAL %s + +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./bad.swift ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-ADDED %s +// RUN: FileCheck -check-prefix=CHECK-RECORD-ADDED %s < %t/main~buildrecord.swiftdeps diff --git a/test/Driver/Dependencies/fail-interface-hash.swift b/test/Driver/Dependencies/fail-interface-hash.swift index 5db2975e87c68..392cc24f996a8 100644 --- a/test/Driver/Dependencies/fail-interface-hash.swift +++ b/test/Driver/Dependencies/fail-interface-hash.swift @@ -23,7 +23,7 @@ // CHECK-SECOND: Handled bad.swift // CHECK-SECOND-NOT: Handled depends -// CHECK-RECORD-DAG: "./bad.swift": !private [ +// CHECK-RECORD-DAG: "./bad.swift": !dirty [ // CHECK-RECORD-DAG: "./main.swift": [ // CHECK-RECORD-DAG: "./depends-on-main.swift": !dirty [ // CHECK-RECORD-DAG: "./depends-on-bad.swift": [ diff --git a/test/Driver/Dependencies/fail-new.swift b/test/Driver/Dependencies/fail-new.swift index f3e3251c5e95f..226098c69a8c0 100644 --- a/test/Driver/Dependencies/fail-new.swift +++ b/test/Driver/Dependencies/fail-new.swift @@ -9,19 +9,30 @@ // CHECK: Handled bad.swift // CHECK-NOT: Handled other.swift -// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-BAD-ONLY %s + +// CHECK-BAD-ONLY-NOT: warning +// CHECK-BAD-ONLY-NOT: Handled +// CHECK-BAD-ONLY: Handled bad.swift +// CHECK-BAD-ONLY-NOT: Handled // RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-OKAY %s // CHECK-OKAY: Handled main.swift // CHECK-OKAY: Handled bad.swift // CHECK-OKAY: Handled other.swift +// CHECK-OKAY-NOT: Handled // RUN: touch -t 201401240006 %t/bad.swift // RUN: rm %t/bad.swiftdeps // RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s // RUN: touch -t 201401240005 %t/* -// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-OKAY %s +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-OKAY-2 %s + +// CHECK-OKAY-2: Handled bad.swift +// CHECK-OKAY-2: Handled other.swift +// CHECK-OKAY-2: Handled main.swift + // RUN: touch -t 201401240006 %t/main.swift // RUN: rm %t/main.swiftdeps // RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./bad.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck %s diff --git a/test/Driver/Dependencies/fail-with-bad-deps.swift b/test/Driver/Dependencies/fail-with-bad-deps.swift new file mode 100644 index 0000000000000..f7e535d89a7e9 --- /dev/null +++ b/test/Driver/Dependencies/fail-with-bad-deps.swift @@ -0,0 +1,47 @@ +/// main ==> depends-on-main | bad ==> depends-on-bad + +// RUN: rm -rf %t && cp -r %S/Inputs/fail-with-bad-deps/ %t +// RUN: touch -t 201401240005 %t/* + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental ./main.swift ./bad.swift ./depends-on-main.swift ./depends-on-bad.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-FIRST %s + +// CHECK-FIRST-NOT: warning +// CHECK-FIRST: Handled main.swift +// CHECK-FIRST: Handled bad.swift +// CHECK-FIRST: Handled depends-on-main.swift +// CHECK-FIRST: Handled depends-on-bad.swift + +// Reset the .swiftdeps files. +// RUN: cp -r %S/Inputs/fail-with-bad-deps/*.swiftdeps %t + +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental ./main.swift ./bad.swift ./depends-on-main.swift ./depends-on-bad.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-NONE %s +// CHECK-NONE-NOT: Handled + +// Reset the .swiftdeps files. +// RUN: cp -r %S/Inputs/fail-with-bad-deps/*.swiftdeps %t + +// RUN: touch -t 201401240006 %t/bad.swift +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental ./main.swift ./bad.swift ./depends-on-main.swift ./depends-on-bad.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-BUILD-ALL %s + +// CHECK-BUILD-ALL-NOT: warning +// CHECK-BUILD-ALL: Handled bad.swift +// CHECK-BUILD-ALL-DAG: Handled main.swift +// CHECK-BUILD-ALL-DAG: Handled depends-on-main.swift +// CHECK-BUILD-ALL-DAG: Handled depends-on-bad.swift + +// Reset the .swiftdeps files. +// RUN: cp -r %S/Inputs/fail-with-bad-deps/*.swiftdeps %t + +// RUN: touch -t 201401240007 %t/bad.swift %t/main.swift +// RUN: cd %t && not %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies-bad.py -output-file-map %t/output.json -incremental ./main.swift ./bad.swift ./depends-on-main.swift ./depends-on-bad.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-WITH-FAIL %s +// RUN: FileCheck -check-prefix=CHECK-RECORD %s < %t/main~buildrecord.swiftdeps + +// CHECK-WITH-FAIL: Handled main.swift +// CHECK-WITH-FAIL-NOT: Handled depends +// CHECK-WITH-FAIL: Handled bad.swift +// CHECK-WITH-FAIL-NOT: Handled depends + +// CHECK-RECORD-DAG: "./bad.swift": !private [ +// CHECK-RECORD-DAG: "./main.swift": [ +// CHECK-RECORD-DAG: "./depends-on-main.swift": !dirty [ +// CHECK-RECORD-DAG: "./depends-on-bad.swift": [ diff --git a/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-1.swift b/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-1.swift new file mode 100644 index 0000000000000..ec20ab4aa0973 --- /dev/null +++ b/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-1.swift @@ -0,0 +1,13 @@ +enum Foo { + case one + case two +} + +func doSomething(_ value: Foo) { + switch value { + case .one: + print("Hello") + case .two: + print("Goodbye") + } +} diff --git a/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-2.swift b/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-2.swift new file mode 100644 index 0000000000000..056314b1d64e1 --- /dev/null +++ b/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-2.swift @@ -0,0 +1,14 @@ +enum Foo { + case one + case two + case three +} + +func doSomething(_ value: Foo) { + switch value { + case .one: + print("Hello") + case .two: + print("Goodbye") + } +} diff --git a/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-3.swift b/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-3.swift new file mode 100644 index 0000000000000..89c1f94a47824 --- /dev/null +++ b/validation-test/Driver/Dependencies/Inputs/rdar25405605/helper-3.swift @@ -0,0 +1,15 @@ +enum Foo { + case one + case two + case three +} + +func doSomething(_ value: Foo) { + switch value { + case .one: + print("Hello") + case .two: + print("Goodbye") + case .three: break + } +} diff --git a/validation-test/Driver/Dependencies/Inputs/rdar25405605/output.json b/validation-test/Driver/Dependencies/Inputs/rdar25405605/output.json new file mode 100644 index 0000000000000..7971d0ca6d0b4 --- /dev/null +++ b/validation-test/Driver/Dependencies/Inputs/rdar25405605/output.json @@ -0,0 +1,13 @@ +{ + "./helper.swift": { + "object": "./helper.o", + "swift-dependencies": "./helper.swiftdeps", + }, + "./main.swift": { + "object": "./main.o", + "swift-dependencies": "./main.swiftdeps", + }, + "": { + "swift-dependencies": "./main~buildrecord.swiftdeps" + } +} diff --git a/validation-test/Driver/Dependencies/rdar25405605.swift b/validation-test/Driver/Dependencies/rdar25405605.swift new file mode 100644 index 0000000000000..7d29f7bfa8399 --- /dev/null +++ b/validation-test/Driver/Dependencies/rdar25405605.swift @@ -0,0 +1,81 @@ +// RUN: rm -rf %t && mkdir %t + +// RUN: cp %s %t/main.swift +// RUN: cp %S/Inputs/rdar25405605/helper-1.swift %t/helper.swift +// RUN: touch -t 201401240005 %t/*.swift + +// RUN: cd %t && %target-build-swift -c -incremental -output-file-map %S/Inputs/rdar25405605/output.json -parse-as-library ./main.swift ./helper.swift -parseable-output -j1 -module-name main 2>&1 | FileCheck -check-prefix=CHECK-1 %s + +// CHECK-1-NOT: warning +// CHECK-1: {{^{$}} +// CHECK-1: "kind": "began" +// CHECK-1: "name": "compile" +// CHECK-1: ".\/main.swift" +// CHECK-1: {{^}$}} + +// CHECK-1: {{^{$}} +// CHECK-1: "kind": "began" +// CHECK-1: "name": "compile" +// CHECK-1: ".\/helper.swift" +// CHECK-1: {{^}$}} + +// RUN: ls %t/ | FileCheck -check-prefix=CHECK-LS %s + +// CHECK-LS-DAG: main.o +// CHECK-LS-DAG: helper.o + +// RUN: cd %t && %target-build-swift -c -incremental -output-file-map %S/Inputs/rdar25405605/output.json -parse-as-library ./main.swift ./helper.swift -parseable-output -j1 -module-name main 2>&1 | FileCheck -check-prefix=CHECK-1-SKIPPED %s + +// CHECK-1-SKIPPED-NOT: warning +// CHECK-1-SKIPPED: {{^{$}} +// CHECK-1-SKIPPED: "kind": "skipped" +// CHECK-1-SKIPPED: "name": "compile" +// CHECK-1-SKIPPED: ".\/main.swift" +// CHECK-1-SKIPPED: {{^}$}} + +// CHECK-1-SKIPPED: {{^{$}} +// CHECK-1-SKIPPED: "kind": "skipped" +// CHECK-1-SKIPPED: "name": "compile" +// CHECK-1-SKIPPED: ".\/helper.swift" +// CHECK-1-SKIPPED: {{^}$}} + +// RUN: cp %S/Inputs/rdar25405605/helper-2.swift %t/helper.swift +// RUN: touch -t 201401240006 %t/helper.swift +// RUN: cd %t && not %target-build-swift -c -incremental -output-file-map %S/Inputs/rdar25405605/output.json -parse-as-library ./main.swift ./helper.swift -parseable-output -j1 -module-name main 2>&1 | FileCheck -check-prefix=CHECK-2 %s + +// CHECK-2-NOT: warning +// CHECK-2: {{^{$}} +// CHECK-2: "kind": "began" +// CHECK-2: "name": "compile" +// CHECK-2: ".\/helper.swift" +// CHECK-2: {{^}$}} + +// CHECK-2: {{^{$}} +// CHECK-2: "kind": "skipped" +// CHECK-2: "name": "compile" +// CHECK-2: ".\/main.swift" +// CHECK-2: {{^}$}} + +// RUN: cp %S/Inputs/rdar25405605/helper-3.swift %t/helper.swift +// RUN: touch -t 201401240007 %t/helper.swift +// RUN: cd %t && not %target-build-swift -c -incremental -output-file-map %S/Inputs/rdar25405605/output.json -parse-as-library ./main.swift ./helper.swift -parseable-output -j1 -module-name main 2>&1 | FileCheck -check-prefix=CHECK-3 %s + +// CHECK-3-NOT: warning +// CHECK-3: {{^{$}} +// CHECK-3: "kind": "began" +// CHECK-3: "name": "compile" +// CHECK-3: ".\/helper.swift" +// CHECK-3: {{^}$}} + +// CHECK-3: {{^{$}} +// CHECK-3: "kind": "began" +// CHECK-3: "name": "compile" +// CHECK-3: ".\/main.swift" +// CHECK-3: {{^}$}} + +func foo(_ value: Foo) -> Bool { + switch value { + case .one: return true + case .two: return false + } +}