From 617b994a6d2632460b8eb66b63a97180a692e4c4 Mon Sep 17 00:00:00 2001 From: David Ungar Date: Mon, 14 May 2018 10:50:54 -0700 Subject: [PATCH] Merge pull request #16526 from davidungar/compilation-failed [Batch Mode] Emit a non-specific error for all primaries lacking specific errors when a batch has errors. --- include/swift/AST/DiagnosticConsumer.h | 42 ++++-- include/swift/AST/DiagnosticEngine.h | 7 +- include/swift/AST/DiagnosticsFrontend.def | 2 + lib/AST/DiagnosticConsumer.cpp | 123 +++++++++++------- lib/AST/DiagnosticEngine.cpp | 12 +- lib/Frontend/SerializedDiagnosticConsumer.cpp | 5 +- lib/FrontendTool/FrontendTool.cpp | 4 +- ...nostics-batch-mode-nonprimary-errors.swift | 17 +++ ...cs-batch-mode-nonprimary-suppression.swift | 26 ---- ...iagnostics-batch-mode-primary-errors.swift | 20 +++ unittests/AST/DiagnosticConsumerTests.cpp | 22 ++-- 11 files changed, 173 insertions(+), 107 deletions(-) create mode 100644 test/Misc/serialized-diagnostics-batch-mode-nonprimary-errors.swift delete mode 100644 test/Misc/serialized-diagnostics-batch-mode-nonprimary-suppression.swift create mode 100644 test/Misc/serialized-diagnostics-batch-mode-primary-errors.swift diff --git a/include/swift/AST/DiagnosticConsumer.h b/include/swift/AST/DiagnosticConsumer.h index 80b5d297e6e2e..16470488f4796 100644 --- a/include/swift/AST/DiagnosticConsumer.h +++ b/include/swift/AST/DiagnosticConsumer.h @@ -100,7 +100,7 @@ class DiagnosticConsumer { const DiagnosticInfo &Info) = 0; /// \returns true if an error occurred while finishing-up. - virtual bool finishProcessing() { return false; } + virtual bool finishProcessing(SourceManager &) { return false; } }; /// \brief DiagnosticConsumer that discards all diagnostics. @@ -140,11 +140,22 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer { /// All consumers owned by this FileSpecificDiagnosticConsumer. const SmallVector SubConsumers; - /// The DiagnosticConsumer may be empty if those diagnostics are not to be - /// emitted. - using ConsumersOrderedByRangeEntry = - std::pair; +public: + // The commented-out consts are there because the data does not change + // but the swap method gets called on this structure. + struct ConsumerSpecificInformation { + /*const*/ CharSourceRange range; + /// The DiagnosticConsumer may be empty if those diagnostics are not to be + /// emitted. + DiagnosticConsumer * /*const*/ consumer; + bool hasAnErrorBeenEmitted = false; + + ConsumerSpecificInformation(const CharSourceRange range, + DiagnosticConsumer *const consumer) + : range(range), consumer(consumer) {} + }; +private: /// The consumers owned by this FileSpecificDiagnosticConsumer, sorted by /// the end locations of each file so that a lookup by position can be done /// using binary search. @@ -153,8 +164,8 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer { /// This allows diagnostics to be emitted before files are actually opened, /// as long as they don't have source locations. /// - /// \see #consumerForLocation - SmallVector ConsumersOrderedByRange; + /// \see #consumerSpecificInformationForLocation + SmallVector ConsumersOrderedByRange; /// Indicates which consumer to send Note diagnostics too. /// @@ -163,7 +174,10 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer { /// /// If None, Note diagnostics are sent to every consumer. /// If null, diagnostics are suppressed. - Optional ConsumerForSubsequentNotes = None; + Optional + ConsumerSpecificInfoForSubsequentNotes = None; + + bool HasAnErrorBeenConsumed = false; public: /// Takes ownership of the DiagnosticConsumers specified in \p consumers. @@ -179,16 +193,22 @@ class FileSpecificDiagnosticConsumer : public DiagnosticConsumer { ArrayRef FormatArgs, const DiagnosticInfo &Info) override; - bool finishProcessing() override; + bool finishProcessing(SourceManager &) override; private: + /// In batch mode, any error causes failure for all primary files, but + /// Xcode will only see an error for a particular primary in that primary's + /// serialized diagnostics file. So, emit errors for all other primaries here. + void addNonSpecificErrors(SourceManager &SM); + void computeConsumersOrderedByRange(SourceManager &SM); /// Returns nullptr if diagnostic is to be suppressed, /// None if diagnostic is to be distributed to every consumer, /// a particular consumer if diagnostic goes there. - Optional consumerForLocation(SourceManager &SM, - SourceLoc loc) const; + Optional + consumerSpecificInformationForLocation(SourceManager &SM, + SourceLoc loc) const; }; } // end namespace swift diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h index 21fecc92cc978..ee37c39b335e7 100644 --- a/include/swift/AST/DiagnosticEngine.h +++ b/include/swift/AST/DiagnosticEngine.h @@ -759,8 +759,8 @@ namespace swift { /// \returns true if any diagnostic consumer gave an error while invoking //// \c finishProcessing. - bool finishProcessing(); - + bool finishProcessing(SourceManager &); + /// \brief Format the given diagnostic text and place the result in the given /// buffer. static void formatDiagnosticText( @@ -781,6 +781,9 @@ namespace swift { /// \brief Send all tentative diagnostics to all diagnostic consumers and /// delete them. void emitTentativeDiagnostics(); + + public: + static const char *diagnosticStringFor(const DiagID id); }; /// \brief Represents a diagnostic transaction. While a transaction is diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 873f0815ad7d3..3335dc16e728e 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -235,6 +235,8 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none, ERROR(error_optimization_remark_pattern, none, "%0 in '%1'", (StringRef, StringRef)) +ERROR(error_compilation_stopped_by_errors_in_other_files,none, "compilation stopped by errors in other files", ()) + #ifndef DIAG_NO_UNDEF # if defined(DIAG) # undef DIAG diff --git a/lib/AST/DiagnosticConsumer.cpp b/lib/AST/DiagnosticConsumer.cpp index 6cebe0c89d528..61c813efa2786 100644 --- a/lib/AST/DiagnosticConsumer.cpp +++ b/lib/AST/DiagnosticConsumer.cpp @@ -17,6 +17,7 @@ #define DEBUG_TYPE "swift-ast" #include "swift/AST/DiagnosticConsumer.h" #include "swift/AST/DiagnosticEngine.h" +#include "swift/AST/DiagnosticsFrontend.h" #include "swift/Basic/Defer.h" #include "swift/Basic/SourceManager.h" #include "llvm/ADT/STLExtras.h" @@ -71,7 +72,8 @@ void FileSpecificDiagnosticConsumer::computeConsumersOrderedByRange( Optional bufferID = SM.getIDForBufferIdentifier(pair.first); assert(bufferID.hasValue() && "consumer registered for unknown file"); CharSourceRange range = SM.getRangeForBuffer(bufferID.getValue()); - ConsumersOrderedByRange.emplace_back(range, pair.second.get()); + ConsumersOrderedByRange.emplace_back( + ConsumerSpecificInformation(range, pair.second.get())); } // Sort the "map" by buffer /end/ location, for use with std::lower_bound @@ -79,36 +81,29 @@ void FileSpecificDiagnosticConsumer::computeConsumersOrderedByRange( // ranges must not be overlapping, but since we need to check end locations // later it's consistent to sort by that here.) std::sort(ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(), - [](const ConsumersOrderedByRangeEntry &left, - const ConsumersOrderedByRangeEntry &right) -> bool { - auto compare = std::less(); - return compare(getRawLoc(left.first.getEnd()).getPointer(), - getRawLoc(right.first.getEnd()).getPointer()); - }); + [](const ConsumerSpecificInformation &left, + const ConsumerSpecificInformation &right) -> bool { + auto compare = std::less(); + return compare(getRawLoc(left.range.getEnd()).getPointer(), + getRawLoc(right.range.getEnd()).getPointer()); + }); // Check that the ranges are non-overlapping. If the files really are all // distinct, this should be trivially true, but if it's ever not we might end // up mis-filing diagnostics. assert(ConsumersOrderedByRange.end() == - std::adjacent_find(ConsumersOrderedByRange.begin(), - ConsumersOrderedByRange.end(), - [](const ConsumersOrderedByRangeEntry &left, - const ConsumersOrderedByRangeEntry &right) { - return left.first.overlaps(right.first); - }) && + std::adjacent_find(ConsumersOrderedByRange.begin(), + ConsumersOrderedByRange.end(), + [](const ConsumerSpecificInformation &left, + const ConsumerSpecificInformation &right) { + return left.range.overlaps(right.range); + }) && "overlapping ranges despite having distinct files"); } -Optional -FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM, - SourceLoc loc) const { - // If there's only one consumer, we'll use it no matter what, because... - // - ...all diagnostics within the file will go to that consumer. - // - ...all diagnostics not within the file will not be claimed by any - // consumer, and so will go to all (one) consumers. - if (SubConsumers.size() == 1) - return SubConsumers.front().second.get(); - +Optional +FileSpecificDiagnosticConsumer::consumerSpecificInformationForLocation( + SourceManager &SM, SourceLoc loc) const { // Diagnostics with invalid locations always go to every consumer. if (loc.isInvalid()) return None; @@ -139,20 +134,19 @@ FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM, // that /might/ contain 'loc'. Specifically, since the ranges are sorted // by end location, it's looking for the first range where the end location // is greater than or equal to 'loc'. - auto possiblyContainingRangeIter = - std::lower_bound(ConsumersOrderedByRange.begin(), - ConsumersOrderedByRange.end(), - loc, - [](const ConsumersOrderedByRangeEntry &entry, - SourceLoc loc) -> bool { - auto compare = std::less(); - return compare(getRawLoc(entry.first.getEnd()).getPointer(), - getRawLoc(loc).getPointer()); - }); + const ConsumerSpecificInformation *possiblyContainingRangeIter = + std::lower_bound( + ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(), loc, + [](const ConsumerSpecificInformation &entry, SourceLoc loc) -> bool { + auto compare = std::less(); + return compare(getRawLoc(entry.range.getEnd()).getPointer(), + getRawLoc(loc).getPointer()); + }); if (possiblyContainingRangeIter != ConsumersOrderedByRange.end() && - possiblyContainingRangeIter->first.contains(loc)) { - return possiblyContainingRangeIter->second; + possiblyContainingRangeIter->range.contains(loc)) { + return const_cast( + possiblyContainingRangeIter); } return None; @@ -163,41 +157,76 @@ void FileSpecificDiagnosticConsumer::handleDiagnostic( StringRef FormatString, ArrayRef FormatArgs, const DiagnosticInfo &Info) { - Optional specificConsumer; + HasAnErrorBeenConsumed |= Kind == DiagnosticKind::Error; + + Optional consumerSpecificInfo; switch (Kind) { case DiagnosticKind::Error: case DiagnosticKind::Warning: case DiagnosticKind::Remark: - specificConsumer = consumerForLocation(SM, Loc); - ConsumerForSubsequentNotes = specificConsumer; + consumerSpecificInfo = consumerSpecificInformationForLocation(SM, Loc); + ConsumerSpecificInfoForSubsequentNotes = consumerSpecificInfo; break; case DiagnosticKind::Note: - specificConsumer = ConsumerForSubsequentNotes; + consumerSpecificInfo = ConsumerSpecificInfoForSubsequentNotes; break; } - - if (!specificConsumer.hasValue()) { + if (!consumerSpecificInfo.hasValue()) { for (auto &subConsumer : SubConsumers) { if (subConsumer.second) { subConsumer.second->handleDiagnostic(SM, Loc, Kind, FormatString, FormatArgs, Info); } } - } else if (DiagnosticConsumer *c = specificConsumer.getValue()) - c->handleDiagnostic(SM, Loc, Kind, FormatString, FormatArgs, Info); - else - ; // Suppress non-primary diagnostic in batch mode. + return; + } + if (!consumerSpecificInfo.getValue()->consumer) + return; // Suppress non-primary diagnostic in batch mode. + + consumerSpecificInfo.getValue()->consumer->handleDiagnostic( + SM, Loc, Kind, FormatString, FormatArgs, Info); + consumerSpecificInfo.getValue()->hasAnErrorBeenEmitted |= + Kind == DiagnosticKind::Error; } -bool FileSpecificDiagnosticConsumer::finishProcessing() { +bool FileSpecificDiagnosticConsumer::finishProcessing(SourceManager &SM) { + addNonSpecificErrors(SM); + // Deliberately don't use std::any_of here because we don't want early-exit // behavior. + bool hadError = false; for (auto &subConsumer : SubConsumers) - hadError |= subConsumer.second && subConsumer.second->finishProcessing(); + hadError |= subConsumer.second && subConsumer.second->finishProcessing(SM); return hadError; } +static void produceNonSpecificError( + FileSpecificDiagnosticConsumer::ConsumerSpecificInformation &info, + SourceManager &SM) { + Diagnostic diagnostic( + diag::error_compilation_stopped_by_errors_in_other_files); + + // Stolen from DiagnosticEngine::emitDiagnostic + DiagnosticInfo Info; + Info.ID = diagnostic.getID(); + + info.consumer->handleDiagnostic( + SM, info.range.getStart(), DiagnosticKind::Error, + DiagnosticEngine::diagnosticStringFor(diagnostic.getID()), {}, Info); +} + +void FileSpecificDiagnosticConsumer::addNonSpecificErrors(SourceManager &SM) { + if (!HasAnErrorBeenConsumed) + return; + for (auto &info : ConsumersOrderedByRange) { + if (!info.hasAnErrorBeenEmitted && info.consumer) { + produceNonSpecificError(info, SM); + info.hasAnErrorBeenEmitted = true; + } + } +} + void NullDiagnosticConsumer::handleDiagnostic( SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind, StringRef FormatString, ArrayRef FormatArgs, diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index d0456a7d7bc12..a781b91176d1d 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -251,10 +251,10 @@ bool DiagnosticEngine::isDiagnosticPointsToFirstBadToken(DiagID ID) const { return storedDiagnosticInfos[(unsigned) ID].pointsToFirstBadToken; } -bool DiagnosticEngine::finishProcessing() { +bool DiagnosticEngine::finishProcessing(SourceManager &SM) { bool hadError = false; for (auto &Consumer : Consumers) { - hadError |= Consumer->finishProcessing(); + hadError |= Consumer->finishProcessing(SM); } return hadError; } @@ -822,9 +822,11 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) { Info.FixIts = diagnostic.getFixIts(); for (auto &Consumer : Consumers) { Consumer->handleDiagnostic(SourceMgr, loc, toDiagnosticKind(behavior), - diagnosticStrings[(unsigned)Info.ID], - diagnostic.getArgs(), - Info); + diagnosticStringFor(Info.ID), + diagnostic.getArgs(), Info); } } +const char *DiagnosticEngine::diagnosticStringFor(const DiagID id) { + return diagnosticStrings[(unsigned)id]; +} diff --git a/lib/Frontend/SerializedDiagnosticConsumer.cpp b/lib/Frontend/SerializedDiagnosticConsumer.cpp index ffd9024b2f025..bf92c314d5c6a 100644 --- a/lib/Frontend/SerializedDiagnosticConsumer.cpp +++ b/lib/Frontend/SerializedDiagnosticConsumer.cpp @@ -140,7 +140,7 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer { assert(CalledFinishProcessing && "did not call finishProcessing()"); } - bool finishProcessing() override { + bool finishProcessing(SourceManager &SM) override { assert(!CalledFinishProcessing && "called finishProcessing() multiple times"); CalledFinishProcessing = true; @@ -160,8 +160,7 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer { llvm::sys::fs::F_None)); if (EC) { // Create a temporary diagnostics engine to print the error to stderr. - SourceManager dummyMgr; - DiagnosticEngine DE(dummyMgr); + DiagnosticEngine DE(SM); PrintingDiagnosticConsumer PDC; DE.addConsumer(PDC); DE.diagnose(SourceLoc(), diag::cannot_open_serialized_file, diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index aed9069513f58..2b4323975f9e1 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -404,7 +404,7 @@ class JSONFixitWriter } } - bool finishProcessing() override { + bool finishProcessing(SourceManager &) override { std::error_code EC; std::unique_ptr OS; OS.reset(new llvm::raw_fd_ostream(FixitsOutputPath, @@ -1651,7 +1651,7 @@ int swift::performFrontend(ArrayRef Args, auto finishDiagProcessing = [&](int retValue) -> int { FinishDiagProcessingCheckRAII.CalledFinishDiagProcessing = true; - bool err = Instance->getDiags().finishProcessing(); + bool err = Instance->getDiags().finishProcessing(Instance->getSourceMgr()); return retValue ? retValue : err; }; diff --git a/test/Misc/serialized-diagnostics-batch-mode-nonprimary-errors.swift b/test/Misc/serialized-diagnostics-batch-mode-nonprimary-errors.swift new file mode 100644 index 0000000000000..7a8166c28fc33 --- /dev/null +++ b/test/Misc/serialized-diagnostics-batch-mode-nonprimary-errors.swift @@ -0,0 +1,17 @@ +// Ensure that an error in a non-primary causes an error in the errorless primary. +// +// RUN: rm -f %t.* + +// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia %S/Inputs/serialized-diagnostics-batch-mode-suppression-helper.swift 2> %t.stderr.txt +// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt +// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt + +// RUN: %FileCheck -check-prefix=NO-GENERAL-ERROR-OCCURRED %s <%t.main.txt +// RUN: %FileCheck -check-prefix=GENERAL-ERROR-OCCURRED %s <%t.empty.txt +// GENERAL-ERROR-OCCURRED: compilation stopped by errors in other files +// NO-GENERAL-ERROR-OCCURRED-NOT: compilation stopped by errors in other files + + +func test(x: SomeType) { + nonexistant() +} diff --git a/test/Misc/serialized-diagnostics-batch-mode-nonprimary-suppression.swift b/test/Misc/serialized-diagnostics-batch-mode-nonprimary-suppression.swift deleted file mode 100644 index 3d32a4787b42f..0000000000000 --- a/test/Misc/serialized-diagnostics-batch-mode-nonprimary-suppression.swift +++ /dev/null @@ -1,26 +0,0 @@ -// To avoid redundant diagnostics showing up in Xcode, batch-mode must suppress diagnostics in -// non-primary files. -// -// RUN: rm -f %t.* - -// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia %S/Inputs/serialized-diagnostics-batch-mode-suppression-helper.swift 2> %t.stderr.txt -// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt -// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt - -// Ensure there was an error: - -// RUN: %FileCheck -check-prefix=ERROR %s <%t.stderr.txt -// ERROR: error: - -// Ensure the error is not in the serialized diagnostics: - -// RUN: %FileCheck -check-prefix=NO-DIAGNOSTICS %s <%t.main.txt -// RUN: %FileCheck -check-prefix=NO-DIAGNOSTICS %s <%t.empty.txt -// NO-DIAGNOSTICS: Number of diagnostics: 0 - -// RUN: %FileCheck -check-prefix=NO-ERROR %s <%t.main.txt -// RUN: %FileCheck -check-prefix=NO-ERROR %s <%t.empty.txt -// NO-ERROR-NOT: error: - -func test(x: SomeType) { -} diff --git a/test/Misc/serialized-diagnostics-batch-mode-primary-errors.swift b/test/Misc/serialized-diagnostics-batch-mode-primary-errors.swift new file mode 100644 index 0000000000000..fd19e8705aa9a --- /dev/null +++ b/test/Misc/serialized-diagnostics-batch-mode-primary-errors.swift @@ -0,0 +1,20 @@ +// Ensure that an error in a primary causes an error in the errorless primary. +// +// RUN: rm -f %t.* + +// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia 2> %t.stderr.txt +// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt +// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt + +// RUN: %FileCheck -check-prefix=ERROR %s <%t.main.txt +// RUN: %FileCheck -check-prefix=NO-NONSPECIFIC-ERROR %s <%t.main.txt +// RUN: %FileCheck -check-prefix=NONSPECIFIC-ERROR %s <%t.empty.txt + +// ERROR: error: +// NONSPECIFIC-ERROR: error: compilation stopped by errors in other files +// NO-NONSPECIFIC-ERROR-NOT: error: compilation stopped by errors in other files + +func test(x: SomeType) { + nonexistent() +} + diff --git a/unittests/AST/DiagnosticConsumerTests.cpp b/unittests/AST/DiagnosticConsumerTests.cpp index 2339395e155d3..2bf15cb561b5d 100644 --- a/unittests/AST/DiagnosticConsumerTests.cpp +++ b/unittests/AST/DiagnosticConsumerTests.cpp @@ -43,7 +43,7 @@ namespace { expected.erase(expected.begin()); } - bool finishProcessing() override { + bool finishProcessing(SourceManager &) override { EXPECT_FALSE(hasFinished); if (previous) EXPECT_TRUE(previous->hasFinished); @@ -68,7 +68,7 @@ TEST(FileSpecificDiagnosticConsumer, SubConsumersFinishInOrder) { consumers.emplace_back("", std::move(consumerUnaffiliated)); FileSpecificDiagnosticConsumer topConsumer(consumers); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, InvalidLocDiagsGoToEveryConsumer) { @@ -89,7 +89,7 @@ TEST(FileSpecificDiagnosticConsumer, InvalidLocDiagsGoToEveryConsumer) { FileSpecificDiagnosticConsumer topConsumer(consumers); topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Error, "dummy", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, ErrorsWithLocationsGoToExpectedConsumers) { @@ -139,7 +139,7 @@ TEST(FileSpecificDiagnosticConsumer, ErrorsWithLocationsGoToExpectedConsumers) { "back", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error, "back", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, @@ -193,7 +193,7 @@ TEST(FileSpecificDiagnosticConsumer, "back", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error, "back", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, WarningsAndRemarksAreTreatedLikeErrors) { @@ -234,7 +234,7 @@ TEST(FileSpecificDiagnosticConsumer, WarningsAndRemarksAreTreatedLikeErrors) { "remark", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Remark, "remark", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrors) { @@ -296,7 +296,7 @@ TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrors) { "note", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note, "note", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToWarningsAndRemarks) { @@ -358,7 +358,7 @@ TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToWarningsAndRemarks) { "note", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note, "note", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrorsEvenAcrossFiles) { @@ -417,7 +417,7 @@ TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrorsEvenAcrossFiles) { "note", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note, "note", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } TEST(FileSpecificDiagnosticConsumer, @@ -480,7 +480,7 @@ TEST(FileSpecificDiagnosticConsumer, "note", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note, "note", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); } @@ -529,5 +529,5 @@ TEST(FileSpecificDiagnosticConsumer, "error", {}, DiagnosticInfo()); topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Note, "note", {}, DiagnosticInfo()); - topConsumer.finishProcessing(); + topConsumer.finishProcessing(sourceMgr); }